概要
JavaScript では、コードは原則として 上から順に同期的(同期処理) に実行されます。
しかし、ファイル操作・タイマー・通信など一部の処理は、環境(ブラウザ / Node.js)が提供する API によって非同期的に実行されます。
※ mdn web docs – 非同期 JavaScript
つまり、
JavaScript 言語仕様そのものは同期的だが、
環境が提供する API の実装によって非同期処理が発生する
という点が重要です。
目次
基本構文
同期処理の例
console.log("A");
console.log("B");
console.log("C");
出力結果
A
B
C
- 上から順に実行される
- 前の処理が終わるまで次に進まない
- JavaScript の基本的な実行モデル
非同期処理の例(setTimeout)
console.log("A");
setTimeout(() => {
console.log("B");
}, 1000);
console.log("C");
出力結果
A
C
B
-
setTimeoutの中身は「あとで」実行される - 処理の完了を待たずに次の行へ進む
同期処理と非同期処理の比較
同期処理
function syncTask() {
console.log("処理開始");
console.log("処理終了");
}
syncTask();
console.log("次の処理");
特徴
- 関数はその場で実行される
- 実行順がコードの記述順と一致する
- 理解しやすいが、重い処理に弱い
非同期処理
function asyncTask() {
setTimeout(() => {
console.log("非同期処理完了");
}, 1000);
}
asyncTask();
console.log("次の処理");
特徴
- 処理の完了を待たない
- 結果はコールバックや Promise で受け取る
- UI フリーズやブロッキングを防げる
活用例
1. ファイル操作(Node.js)
同期版
const fs = require("fs");
const data = fs.readFileSync("sample.txt", "utf-8");
console.log(data);
- ファイル読み込みが終わるまで処理が止まる
非同期版
const fs = require("fs");
fs.readFile("sample.txt", "utf-8", (err, data) => {
if (err) return;
console.log(data);
});
- 読み込み完了後にコールバックが呼ばれる
2. Promise を使った非同期処理
fetch("https://example.com/data.json")
.then(res => res.json())
.then(data => {
console.log(data);
});
- 非同期処理をチェーンで表現できる
- コールバック地獄を回避できる
3. async / await による同期風の記述
async function loadData() {
const res = await fetch("https://example.com/data.json");
const data = await res.json();
console.log(data);
}
loadData();
- 見た目は同期処理
- 内部では非同期処理として動作
4. 同期・非同期の混在例
console.log("開始");
setTimeout(() => {
console.log("タイマー");
}, 0);
console.log("終了");
出力結果
開始
終了
タイマー
- 非同期処理は「あとで」実行される
参考リンク
- mdn web docs – 非同期 JavaScript
- mdn web docs – setTimeout
- Node.js fs.readFile
- Promise - JavaScript | MDN