JavaScriptの非同期処理とは?基本をわかりやすく解説

JavaScriptを学んでいると、「非同期処理」という言葉を頻繁に目にします。
API通信やファイルの読み込み、タイマー処理など、多くの場面で使われる重要な仕組みです。
しかし、次のような疑問を持つことも少なくありません。
- 非同期処理とは何か
- 同期処理と何が違うのか
- なぜ処理の順番が思った通りにならないのか
- Promiseやasync/awaitとどう関係するのか
この記事では、JavaScriptの非同期処理の基本を、仕組みから具体例まで丁寧に解説します。
この記事を読むことで、Promiseやasync/awaitを学ぶ前提知識をしっかり理解できます。
Contents
- 1 非同期処理とは何か
- 2 非同期処理の例
- 3 非同期処理が必要な理由
- 4 同期処理と非同期処理の違い
- 5 setTimeout()で学ぶ非同期処理
- 6 コールバック関数と非同期処理
- 7 非同期処理でよくある問題
- 8 Promiseとは
- 9 async/awaitとは
- 10 awaitの役割
- 11 非同期処理のエラー処理
- 12 Promise.all()で複数の非同期処理をまとめて実行する
- 13 fetch()と非同期処理
- 14 非同期処理の流れ
- 15 非同期処理とイベントループ
- 16 非同期処理を理解するための重要ポイント
- 17 非同期処理でよく使う機能
- 18 非同期処理でよくある間違い
- 19 非同期処理の学習順序
- 20 まとめ
- 21 関連記事
非同期処理とは何か
非同期処理とは、ある処理の完了を待たずに、次の処理へ進む仕組みです。
通常の処理では、上から順番に1つずつ実行されます。これを同期処理と呼びます。
一方で非同期処理では、時間のかかる処理を開始した後、その完了を待たずに次の処理を実行します。
同期処理の例
console.log("1");
console.log("2");
console.log("3");実行結果
1
2
3上から順番に確実に実行されます。
非同期処理の例
console.log("1");
setTimeout(() => {
console.log("2");
}, 1000);
console.log("3");実行結果
1
3
2setTimeout() の処理は1秒後に実行されるため、その完了を待たずに次の console.log("3") が先に実行されます。
非同期処理が必要な理由
時間のかかる処理を待ち続けると、プログラム全体が停止したように見えてしまいます。
非同期処理を使うことで、他の処理を止めずに実行できます。
非同期処理が使われる例
- API通信
- ファイルの読み込み
- 画像の読み込み
- タイマー処理
- データベースアクセス
同期処理と非同期処理の違い
| 項目 | 同期処理 | 非同期処理 |
|---|---|---|
| 実行順序 | 完了してから次へ進む | 完了を待たずに次へ進む |
| 処理速度 | 遅い処理で全体が止まる | 他の処理を継続できる |
| 主な用途 | 計算や通常処理 | 通信や読み込み |
setTimeout()で学ぶ非同期処理
setTimeout() は、一定時間後に処理を実行する代表的な非同期処理です。
console.log("開始");
setTimeout(() => {
console.log("1秒後に実行");
}, 1000);
console.log("終了");実行結果
開始
終了
1秒後に実行コールバック関数と非同期処理
非同期処理では、処理完了後に実行する関数を渡すことがあります。これをコールバック関数と呼びます。
コールバック関数の基本は、[JavaScriptのコールバック関数とは?基本から実践まで徹底解説]で詳しく解説しています。
setTimeout(() => {
console.log("処理完了");
}, 1000);この無名関数がコールバック関数です。
非同期処理でよくある問題
非同期処理では、処理が完了する前に結果を使おうとしてしまうことがあります。
let result;
setTimeout(() => {
result = "完了";
}, 1000);
console.log(result);実行結果
undefinedsetTimeout() の処理がまだ終わっていないためです。
Promiseとは
Promiseは、非同期処理の完了状態を表すオブジェクトです。
状態は3つあります。
- pending(処理中)
- fulfilled(成功)
- rejected(失敗)
Promiseの基本は、[JavaScriptのPromiseとは?非同期処理の基本をわかりやすく解説]で詳しく解説しています。
Promiseの基本例
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve("完了しました");
}, 1000);
});
promise.then((result) => {
console.log(result);
});実行結果
完了しましたasync/awaitとは
async/await は、Promiseをより読みやすく書くための構文です。
Promiseチェーンでは .then() を連続して記述しますが、async/await を使うと同期処理のように上から順番に書けます。
async/awaitの基本は、[JavaScriptのasync/awaitとは?非同期処理の仕組みを基礎から解説]で詳しく解説しています。
async/awaitの基本例
function wait(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve("完了しました");
}, ms);
});
}
async function main() {
const result = await wait(1000);
console.log(result);
}
main();実行結果
完了しましたawaitの役割
await は、Promiseの完了を待ってから次の処理へ進みます。
function wait(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve("待機終了");
}, ms);
});
}
async function main() {
console.log("開始");
const result = await wait(1000);
console.log(result);
console.log("終了");
}
main();実行結果
開始
待機終了
終了非同期処理のエラー処理
非同期処理ではエラーが発生することがあります。
Promiseでのエラー処理
const promise = new Promise((resolve, reject) => {
reject(new Error("エラーが発生しました"));
});
promise.catch((error) => {
console.log(error.message);
});実行結果
エラーが発生しましたasync/awaitでのエラー処理
function fail() {
return new Promise((resolve, reject) => {
reject(new Error("エラーが発生しました"));
});
}
async function main() {
try {
await fail();
} catch (error) {
console.log(error.message);
}
}
main();実行結果
エラーが発生しましたtry...catch の基本は、[JavaScriptのtry/catchとは?エラー処理の基本と使い方を徹底解説]で詳しく解説しています。
Promise.all()で複数の非同期処理をまとめて実行する
複数の非同期処理を同時に実行し、すべて完了してから結果を取得したい場合は Promise.all() を使います。
function wait(ms, message) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(message);
}, ms);
});
}
async function main() {
const results = await Promise.all([
wait(1000, "1つ目"),
wait(500, "2つ目"),
wait(1500, "3つ目")
]);
console.log(results);
}
main();実行結果
["1つ目", "2つ目", "3つ目"]Promise.all() の詳細は、[JavaScriptのPromise.allとは?複数の非同期処理をまとめて実行する方法]で解説しています。
fetch()と非同期処理
Web APIからデータを取得する fetch() も非同期処理です。
async function main() {
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await response.json();
console.log(data.title);
}
main();非同期処理の流れ
非同期処理の基本的な流れは次の通りです。
- 時間のかかる処理を開始する
- 完了を待たずに次の処理へ進む
- 完了したらコールバックやPromiseで結果を受け取る
非同期処理とイベントループ
JavaScriptは1つのスレッドで動作しますが、非同期処理によって複数の作業を効率的に扱えます。
この仕組みを支えているのがイベントループです。
イベントループの概要
- 同期処理を実行する
- 非同期処理を登録する
- 同期処理を続ける
- 非同期処理が完了すると実行待ちになる
- メイン処理が空いたタイミングで実行される
非同期処理を理解するための重要ポイント
順番通りに書いても順番通りに実行されるとは限らない
非同期処理では、コードの記述順と実行順が異なることがあります。
Promiseは非同期処理の結果を表す
成功・失敗・処理中という状態を持ちます。
async/awaitで読みやすく書ける
同期処理のような見た目で記述できます。
非同期処理でよく使う機能
setTimeout()setInterval()fetch()PromisePromise.all()async/await
非同期処理でよくある間違い
awaitを使うにはasyncが必要
async function main() {
await Promise.resolve();
}
main();Promiseを返さない関数にawaitを使っても意味がない
async function main() {
const result = await 123;
console.log(result);
}
main();実行結果
123非同期処理の学習順序
非同期処理は次の順番で学ぶと理解しやすくなります。
- コールバック関数
- Promise
.then().catch()- async/await
- Promise.all()
まとめ
JavaScriptの非同期処理とは、時間のかかる処理を待たずに次の処理を進める仕組みです。
- 同期処理は完了してから次へ進む
- 非同期処理は完了を待たずに次へ進む
setTimeout()は代表的な非同期処理- Promiseは非同期処理の結果を表す
- async/awaitで読みやすく書ける
try...catchでエラー処理ができるPromise.all()で複数処理をまとめられる
非同期処理を理解すると、API通信やファイル操作など実践的なJavaScriptを扱えるようになります。

