JavaScriptの非同期処理は、時間のかかるタスク(ネットワークリクエスト、ファイルの読み書き、タイマーなど)をブロックせずに実行するための方法です。非同期処理を使用すると、ユーザーインターフェースをスムーズに保ちながら、他のタスクを並行して実行できます。
非同期処理の主な方法
- コールバック(Callbacks)
- プロミス(Promises)
async
/await
構文
1. コールバック(Callbacks)
コールバックは、非同期タスクが完了したときに呼び出される関数です。コールバックは関数の引数として渡され、タスクが完了したときに実行されます。
基本的な構文
function asyncTask(callback) {
setTimeout(() => {
callback("タスク完了");
}, 1000);
}
asyncTask((message) => {
console.log(message); // 1秒後に "タスク完了" が表示される
});
コールバック地獄(Callback Hell)
複数の非同期タスクを順番に実行する場合、コールバックのネストが深くなることがあります。これを「コールバック地獄」と呼びます。
function task1(callback) {
setTimeout(() => {
console.log("タスク1完了");
callback();
}, 1000);
}
function task2(callback) {
setTimeout(() => {
console.log("タスク2完了");
callback();
}, 1000);
}
function task3(callback) {
setTimeout(() => {
console.log("タスク3完了");
callback();
}, 1000);
}
task1(() => {
task2(() => {
task3(() => {
console.log("すべてのタスク完了");
});
});
});
2. プロミス(Promises)
プロミスは、非同期操作の最終的な完了(または失敗)を表すオブジェクトです。プロミスは、then
、catch
、finally
メソッドを使用して、非同期タスクの結果を処理します。
基本的な構文
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("タスク完了");
}, 1000);
});
promise.then((message) => {
console.log(message); // 1秒後に "タスク完了" が表示される
}).catch((error) => {
console.error(error);
});
プロミスチェーン
プロミスチェーンを使用すると、複数の非同期タスクを順番に実行できます。
function task1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク1完了");
resolve();
}, 1000);
});
}
function task2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク2完了");
resolve();
}, 1000);
});
}
function task3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク3完了");
resolve();
}, 1000);
});
}
task1()
.then(task2)
.then(task3)
.then(() => {
console.log("すべてのタスク完了");
})
.catch((error) => {
console.error(error);
});
3. async
/await
構文
async
/await
は、プロミスをよりシンプルに扱うための構文糖です。async
関数はプロミスを返し、await
はプロミスが解決されるまで待機します。
基本的な構文
async function asyncTask() {
let result = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("タスク完了");
}, 1000);
});
console.log(result); // 1秒後に "タスク完了" が表示される
}
asyncTask();
非同期タスクの順序実行
async
/await
を使用すると、非同期タスクを同期的なコードのように記述できます。
function task1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク1完了");
resolve();
}, 1000);
});
}
function task2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク2完了");
resolve();
}, 1000);
});
}
function task3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("タスク3完了");
resolve();
}, 1000);
});
}
async function runTasks() {
try {
await task1();
await task2();
await task3();
console.log("すべてのタスク完了");
} catch (error) {
console.error(error);
}
}
runTasks();
非同期処理の選択基準
- コールバック: 単純な非同期処理には便利ですが、複雑な処理ではコールバック地獄に陥りやすいです。
- プロミス: コールバック地獄を避け、非同期タスクのチェーンを簡単に管理できます。
async
/await
: 非同期処理を同期的なコードのように書くことができ、可読性が高まります。
まとめ
- コールバック: 関数の引数として渡され、非同期タスクの完了後に実行される関数。
- プロミス: 非同期操作の最終的な完了(または失敗)を表すオブジェクト。
then
、catch
、finally
メソッドで結果を処理。 async
/await
構文: プロミスを扱うための構文糖。非同期タスクを同期的なコードのように記述できる。
これでJavaScriptの非同期処理についての基本的な理解が深まったと思います。
スポンサーリンク