もう怖くない!JavaScriptの非同期処理 async/await が驚くほど分かるようになる話 公開日: 2025年9月12日 JavaScriptの学習で、多くの人が一度は巨大な壁として感じること。それが「非同期処理」ではないでしょうか。 Promise、.then()、コールバック地獄…考えただけで頭が痛くなる、という人もいるかもしれません。 僕自身、エンジニアになりたての頃、この非同期処理に何度も泣かされました。 当時、天気予報APIからデータを取得して表示するだけの簡単なアプリを作っていたのですが、.then()の中にまた.then()を書き、気づけばコードが右へ右へとネスト(入れ子)していく...。 「一体どのコードがどの順番で動いているんだ…?」とパニックになり、コンソールログを10個くらい仕込んで順番を確認していたのを覚えています。 しかし、現代のJavaScriptには、そんな悪夢のような非同期処理を、まるで同期処理(上から順番に実行される普通のコード)のように、直感的に書けるようにしてくれる魔法があります。 それが、async/await です。 今日は、この async/await が、一体何をしていて、なぜこんなに便利なのかを、僕なりの言葉で解説してみたいと思います。 前提:なぜ非同期処理が必要なのか? まず、なぜJavaScriptには非同期処理という面倒な仕組みがあるのでしょうか? それは、「時間のかかる処理」の待ち時間で、他の作業を止めてしまわないようにするためです。 レストランのウェイターを想像してください。 Aさんの注文(時間のかかる処理)をキッチンに伝えた後、料理が出来上がるまでAさんのテーブルの前でずっと待ち続けるウェイターがいたら、どうでしょう?その間、BさんやCさんは永遠に注文できません。レストランは回りませんよね。 優秀なウェイターは、Aさんの注文を伝えたら、すぐにBさんの注文を取りに行きます。そして、キッチンから「Aさんの料理ができました!」と呼ばれたら、Aさんの元へ料理を運びに行きます。これが非同期処理の考え方です。 async/await 登場前の世界 (.then()チェーン) async/await が登場する前は、この「料理ができたら、これをしてね」という繋がりを、.then() というメソッドで鎖(チェーン)のように繋げて書いていました。 僕が当時苦しんでいたコードは、まさにこんな感じでした。 // ユーザー情報をAPIから取ってくる例 fetch('https://api.example.com/user/1') .then(response => { // 最初の処理(レスポンスをJSONに変換) return response.json(); }) .then(user => { // 次の処理(ユーザー名を表示) console.log(user.name); }) .catch(error => { // もし途中でエラーが起きたら console.error('エラーが発生しました:', error); }); これでも動きますが、処理が3つ、4つと増えていくと、then がどんどん連なり、コードは読みにくくなっていきます。僕はここで「閉じカッコ」の数を間違えてエラーになる、というミスを何百回とやりました。 async/await という魔法 async/await は、この.then()チェーンを、まるで魔法のように書き換えてくれます。 // async/await を使った同じ処理 async function fetchUser() { try { const response = await fetch('https://api.example.com/user/1'); const user = await response.json(); console.log(user.name); } catch (error) { console.error('エラーが発生しました:', error); } } fetchUser(); どうでしょうか?.then() がなくなり、普通のプログラムのように、コードが上から下に流れているように見えませんか? 初めてこの書き方を知った時、「えっ、これでいいの? あの苦労は何だったんだ」と衝撃を受けたのを覚えています。これこそが async/await の最大のメリットです。 async と await の役割 この魔法を理解するためのキーワードは2つだけです。 async 関数の前につける「宣言」です。 「この fetchUser 関数の中では、時間のかかる非同期処理が出てきますよ。だから、この関数全体を『待たせることのできる特別な関数』として扱ってくださいね」と、JavaScriptエンジンに教えてあげる役割です。 async をつけた関数は、必ず Promise という「結果がいつか返ってくる約束手形」を返すようになります。 await Promise を返す可能性のある処理(fetch やresponse.json() など)の前に置きます。 「この fetch() という処理は時間がかかるので、結果が返ってくるまで、ここで一旦処理を『待って』ください」という意味です。 await は、async がついた関数の中でしか使えません。 ウェイターの例で言うなら、async function が「これから注文を取りに行くぞ」という宣言で、await が「料理が出来上がるまで、ちょっとここで待機!」という具体的な行動です。でも、レストラン全体(ブラウザ)は止まらず、他の作業を続けてくれます。 実務でも、僕は async/await を使う時は必ず try...catch で囲むようにしています。await を使った処理でエラーが起きると、catch ブロックで一括してエラー処理ができるので、コードが非常にクリーンになり、バグを見つけやすくなるからです。 まとめ もしあなたが今、昔の僕のように .then() チェーンやコールバック地獄で頭を抱えているなら、ぜひ async/await を使ってみてください。 最初は「おまじない」のように感じるかもしれませんが、使っていくうちに、その直感的な分かりやすさと、コードの綺麗さに感動するはずです。 「SerchCode Pro」で async や await と検索して、色々な用例を見てみるのも、理解を深めるのに役立ちますよ。 #プログラミング #プログラミング 勉強 #プログラミング 初心者 実際に試してみよう! 記事で紹介したコードがよく分からなかったり、ご自身のコードについてもっと知りたい場合は、AIコード解説ツールが便利です。コードを貼り付けるだけで、AIが日本語で分かりやすく解説します。 AIコード解説ツールを使ってみる →