結論:非同期処理とは「時間のかかる処理の完了を待っている間、プログラムを固まらせない」ための仕組みで、JavaScriptでは Promise という「あとで結果が来る箱」を、async/await という書き方で「同期コードのように」扱います。 言葉で理解しようとするより、実際に動くコードを書いて「待たせている」「待っている」を目で確認するのが一番の近道です。
そもそも「同期」と「非同期」の違いとは
同期処理は、上から書いた順番に1行ずつ実行され、前の行が終わるまで次の行に進みません。ボタンを押したらレジの行に並んで自分の番が来るまでひたすら待つ、あの感覚です。
非同期処理は、時間のかかる処理(通信・ファイル読み込み・タイマーなど)を「あとで終わったら教えて」と横に置いておき、その間に他の処理を進められる仕組みです。レストランで注文だけ済ませて、料理ができるまで他のことをしていられる、あの感覚に近いです。
Webアプリでは「サーバーにデータを取りに行く」「一定時間待つ」といった処理が頻繁に発生します。これを同期的に(=待ちきるまで固まる形で)書いてしまうと、通信が終わるまで画面がフリーズしたようになります。だから非同期処理の考え方は避けて通れません。
Promiseとは何か(初心者向け)
**Promise とは、「いずれ結果が返ってくる処理」を表す入れ物(オブジェクト)**です。今すぐ結果はわからないけれど、「成功したらこの値を渡す」「失敗したらこのエラーを渡す」という約束だけを先に受け取れます。
Promise には3つの状態があります。
- 待機中(まだ結果が出ていない)
- 成功(
resolveされた) - 失敗(
rejectされた)
成功時の処理は .then()、失敗時の処理は .catch() で書くのが基本形です。ここまでが「Promiseとは」の答えになりますが、実際に手を動かして「待って、結果が届く」流れを見た方が圧倒的に理解が早いです。Promise と async/await ― 非同期の基本 では、new Promise の作り方から .then() の使い方まで、ブラウザ上でそのまま実行しながら確認できます(無料・登録不要)。
async/awaitの使い方
Promise の .then() を重ねて書いていくと、処理が増えるほどコードが右にどんどんネストして読みにくくなります。これを解消するのが async/await です。
- 関数の前に
asyncを付けると、その関数は自動的に Promise を返すようになり、中でawaitが使えるようになります。 awaitを Promise の前に置くと、「その Promise の結果が出るまで、この行で待つ」という意味になります。見た目は同期コードとほぼ同じになるので、読みやすくなります。
async function main() {
const msg = await wait(50); // ここで結果が出るまで待つ
console.log("結果:", msg);
}
失敗(エラー)は try / catch で受け止めます。.catch() を都度書く代わりに、同期処理と同じ感覚で例外処理が書けるのが async/await の利点です。この一連の流れは Promise と async/await ― 非同期の基本 の演習で実際に手を動かしながら体験できます。
非同期処理が最も実感できるのは、実際に「サーバーからデータを取ってくる」場面です。fetch ― サーバーからデータを取ってくる では、fetch が Promise を返すこと、await で2段階(通信の完了・本文の変換)を待つ必要があることを、模擬サーバーを使ってブラウザ内でそのまま動かして確認できます。JavaScriptコース自体はコーストップから全28レッスンすべてブラウザで実行可能なので、非同期のあたりで詰まったら、その前の配列メソッド ― map / filter / find や関数の定義 まで戻って復習するのも有効です。
つまずきやすいところ
非同期処理でよくあるつまずきをいくつか挙げます。
awaitはasync関数の中でしか使えない:普通の関数の中でうっかりawaitを書いてしまうと、コードが読み込まれた時点でエラーになります。これは詳しく await is only valid in async functions ― async の付け忘れ(JavaScriptのエラー逆引き)で、出るエラーメッセージと直し方をセットで確認できます。awaitを付け忘れると Promise そのものが返ってくる:console.logした結果が期待した値ではなくPromise { <pending> }のようなものになっていたら、awaitの付け忘れを疑ってください。- 失敗時の処理を書き忘れる:通信は失敗することがあります。
try / catch(または.catch())を書かずに放置すると、エラーが握りつぶされたように見えて原因調査が難航します。必ず失敗パターンも一度は書いて動かしてみましょう。
「非同期処理がわからない」と感じる原因の多くは、こうした細かい文法上のルールを一度も実際のエラーとして体験していないことにあります。エラーメッセージを読んで直すところまでをセットで経験しておくと、実務でも独学でも詰まりにくくなります。
C#でも同じ考え方を使う
非同期処理の考え方はJavaScriptだけのものではありません。C#にも Task と async/await があり、考え方はほぼ共通しています。「待っている間プログラムを固めない」という目的は同じで、JavaScriptの Promise にあたるのが C# の Task です。
C#実践コースの なぜ非同期か ― Task と async/await から始めると、Task.Delay で「待つ」感覚を体験できます。そのあと 戻り値のある非同期(Task<T>) で「待った後に値を受け取る」パターン、並行実行(WhenAll) で複数の非同期処理を同時に走らせる方法まで、すべてブラウザ上でそのまま実行しながら学べます。JavaScriptとC#の両方で非同期処理を書いてみると、「言語が違っても考え方は同じ」ということが実感でき、理解がぐっと深まります。
次に読む
- JavaScriptコース — 全28レッスン、すべてブラウザで実行可能。非同期はjavascript-25とjavascript-28。
- C#実践コース — 非同期は第1章(csharp-practice-1-async-basics 〜 csharp-practice-3-when-all)で集中的に扱う。
- JavaScriptのエラー逆引き —
await関連のエラーで詰まったらまずここ。 - JavaScript独学ロードマップ — 非同期処理を学ぶ前後にどんな順序で学習を進めるべきかをまとめた記事。