JavaScriptのasync/awaitとは?非同期処理の仕組みを基礎から解説

JavaScriptの非同期処理とasync/awaitの概念を表す、文字を含まない抽象的な図解。左側の複雑で非同期なネットワークが中央の光輝く垂直なゲート(await)を通過し、右側の整理された順序正しい緑色のデータフロー(同期的な実行)へと統合されています。
async/awaitによる非同期処理の制御メカニズム:複雑な非同期ネットワークを「await」という中央の焦点を通して、予測可能な順序へと整列させる概念図。

JavaScriptで効率的なプログラムを書くために避けて通れないのが「非同期処理」です。その中でも、現代のフロントエンド開発で主流となっているのがasync/awaitという構文です。

この記事では、非同期処理の概念からasync/awaitの具体的な使い方、エラーハンドリングまで、初心者の方にもわかりやすく丁寧に解説します。

非同期処理とは何か

通常、プログラミングの処理は上から下へと順番に実行されます。これを「同期処理」と呼びます。しかし、ネットワーク通信やタイマー処理のように、完了までに時間がかかる処理を同期的に行うと、その間プログラムが停止してしまいます。

これを防ぐために、「時間のかかる処理の完了を待たずに、次の処理を進める」仕組みが非同期処理です。

Promiseとの関係

以前のJavaScriptでは、非同期処理を扱うためにPromiseが広く使われていました。async/awaitは、このPromiseをより直感的で、同期処理のように読みやすく書けるようにした「糖衣構文(シンタックスシュガー)」です。

async関数の基本

asyncは、その関数が非同期処理を含むことを宣言するキーワードです。関数の前にasyncを付けるだけで、その関数は常にPromiseオブジェクトを返すようになります。

// async関数の定義
async function sampleFunction() {
  return "Hello, Async!";
}

// 実行するとPromiseが返される
sampleFunction().then(value => {
  console.log(value); // "Hello, Async!"
});

内部で値を直接リターンしても、自動的にPromise.resolve()でラップされるのが特徴です。

awaitの使い方とメリット

awaitは、async関数の中でのみ使用できるキーワードです。Promiseの処理が完了するまで一時停止し、その結果(解決された値)を直接変数に代入できます。

従来のPromiseとの比較

これまでの.then()を使った書き方と比較してみましょう。

【Promise形式】

function fetchData() {
  fetch("https://api.example.com/data")
    .then(response => response.json())
    .then(data => console.log(data));
}

【async/await形式】

async function fetchData() {
  // 処理が終わるまで待機し、結果を代入する
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();
  console.log(data);
}

後者の方がネスト(階層)が深くならず、上から下へ順番に処理が流れるため、コードの可読性が飛躍的に向上します。

エラーハンドリング(try…catch)

非同期処理でエラーが発生した場合、async/awaitでは標準的なtry...catch構文を使用してエラーを捕捉します。これにより、同期処理と同様の感覚で例外処理を記述できます。

async function safeFetch() {
  try {
    const response = await fetch("https://invalid-url.com");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("データの取得に失敗しました:", error);
  } finally {
    console.log("処理が終了しました");
  }
}

safeFetch();

ネットワークエラーやJSON解析の失敗など、予期せぬトラブルにも柔軟に対応可能です。

実践的な活用シーン

async/awaitは、特に以下のような場面で力を発揮します。

  1. Web APIからのデータ取得: 外部サーバーと通信し、情報を表示する場合。
  2. データベース操作: データの保存や更新が完了するのを待ってから次の画面へ遷移させる場合。
  3. ファイルの読み書き: Node.js環境などで、大きなファイルを順番に処理する場合。

複数の非同期処理を順番に行いたい場合、awaitを並べるだけで「1つ目が終わったら2つ目」という制御が確実に行えます。

まとめ

async/awaitは、複雑になりがちな非同期処理をシンプルかつ安全に記述するための強力な武器です。

  • asyncを付けて関数を定義する。
  • awaitで処理の完了を待機する。
  • try...catchでエラーを管理する。

この3点を押さえることで、JavaScriptのコードはより堅牢でメンテナンスしやすいものになります。ぜひ実際の開発に取り入れてみてください。

関連記事