JavaScriptの非同期処理を初心者向けに解説|Promiseとasync/awaitの仕組み・実行タイミングを理解する方法

JavaScript

JavaScriptを学習していると、多くの初心者がつまずくポイントの1つが非同期処理です。通常の上から順番に実行される処理とは違い、時間のかかる処理を待たずに次の処理へ進む仕組みのため、実行される順番が分かりにくく感じることがあります。

特にPromiseやasync/awaitは、Webアプリ開発やAPI通信などで頻繁に利用される重要な機能です。しかし、仕組みを理解せずに書き方だけ覚えると、エラー処理や処理の順番で混乱しやすくなります。

この記事では、JavaScriptの非同期処理がなぜ必要なのか、Promiseやasync/awaitがどのように動いているのかを、初心者にも分かりやすい具体例を交えながら解説します。

JavaScriptの非同期処理とは何か?基本的な考え方を理解する

JavaScriptの処理は基本的に上から順番に実行されます。このような処理を同期処理と呼びます。

例えば以下のコードでは、1、2、3の順番で表示されます。

console.log(“1”);
console.log(“2”);
console.log(“3”);

しかし、Webサイトでは通信処理やファイル読み込みなど、完了まで時間がかかる処理があります。その処理が終わるまで全体を停止すると、画面が固まったように見えてしまいます。

そこでJavaScriptでは、時間のかかる処理を別に進め、完了したタイミングで結果を受け取る非同期処理という仕組みが使われています。

非同期処理が必要になる具体的な場面

非同期処理は、特に外部との通信が必要な場面で重要になります。例えば、天気情報を取得するWebアプリでは、サーバーからデータが返ってくるまで数秒かかる場合があります。

もし通信中にJavaScript全体が停止すると、ユーザーはボタンを押せなくなったり、画面操作ができなくなったりします。

そのため、JavaScriptでは通信を開始した後、結果を待っている間にも別の処理を続けられるようになっています。

代表的な非同期処理の例には、以下のようなものがあります。

  • APIからデータを取得する処理
  • 画像やファイルを読み込む処理
  • タイマー処理
  • データベースとの通信

Promiseとは非同期処理の結果を管理する仕組み

Promiseは、非同期処理の結果を管理するためのJavaScriptの仕組みです。簡単に言うと、「あとで結果を返します」という約束を表すオブジェクトです。

Promiseには主に3つの状態があります。

状態 意味
pending 処理中の状態
fulfilled 処理が成功した状態
rejected 処理が失敗した状態

例えばデータ取得処理では、最初はpending状態ですが、通信が成功するとfulfilledになり、失敗するとrejectedになります。

Promiseではthenやcatchを使って、成功時と失敗時の処理を分けて書くことができます。

fetch(“https://example.com/data”)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log(error));

async/awaitを使うと非同期処理を読みやすく書ける

async/awaitはPromiseをより分かりやすく書くための構文です。非同期処理を、通常の同期処理に近い形で記述できます。

例えばPromiseを使った処理は、async/awaitでは以下のように書けます。

async function getData() {
  try {
    const response = await fetch(“https://example.com/data”);
    const data = await response.json();
    console.log(data);
  } catch(error) {
    console.log(error);
  }
}

awaitを書くことで、「この処理が終わるまで次へ進まない」という形で記述できます。ただし、実際にはJavaScript全体が停止しているわけではなく、その関数内だけが待機しています。

初心者が混乱しやすい非同期処理のタイミングを理解するコツ

非同期処理を理解するには、「コードを書いた順番」と「実行される順番」は必ずしも同じではないことを意識することが大切です。

例えば以下のコードでは、タイマー処理は後から実行されます。

console.log(“開始”);
setTimeout(() => {
  console.log(“タイマー処理”);
}, 1000);
console.log(“終了”);

実行結果は以下のようになります。

開始
終了
タイマー処理

タイマーを1秒後に設定しているため、JavaScriptは待たずに次の処理へ進みます。このような動きを理解することが非同期処理を学ぶ第一歩です。

Promiseやasync/awaitを理解するための効果的な学習方法

非同期処理は、最初から複雑なAPI通信などで学ぶより、小さな実験コードを書くことがおすすめです。

例えばsetTimeoutを使って、「どの順番で表示されるか」を確認すると、処理の流れを体感できます。

また、Promiseを使った処理をasync/awaitへ書き換える練習をすると、それぞれの関係性が理解しやすくなります。

学習時には以下の順番で進めると理解しやすくなります。

  1. 同期処理と非同期処理の違いを理解する
  2. setTimeoutなどで実行タイミングを確認する
  3. Promiseの状態とthen/catchを理解する
  4. async/awaitで読みやすいコードを書く

非同期処理でよくあるエラーと対処方法

初心者によくあるミスは、非同期処理の完了前に結果を使おうとしてしまうことです。

例えば通信結果を取得する前に変数を参照すると、undefinedになったり、期待した値が取得できなかったりします。

また、awaitを書き忘れたり、asyncを付け忘れたりするエラーも多くあります。

エラーが発生した場合は、処理の途中にconsole.logを入れて、「どのタイミングで値が変化しているか」を確認すると原因を見つけやすくなります。

まとめ

JavaScriptの非同期処理は、時間のかかる処理を止めずに実行するための重要な仕組みです。Promiseは非同期処理の結果を管理し、async/awaitはPromiseをより読みやすく扱うための書き方です。

初心者の場合は、まず実行順序を確認する小さなコードを書き、処理がいつ実行されるのかを理解することが大切です。

非同期処理は最初は難しく感じますが、Promiseとasync/awaitの関係を理解すると、Webアプリ開発やAPI連携など幅広い場面で役立つJavaScriptの重要な技術になります。

コメント

タイトルとURLをコピーしました