ShiraBlog

  • async awaitの使い方を理解する

    async awaitの基本的な使い方と、Promiseとの違いについて解説します。非同期処理を簡潔に記述するための方法として、async awaitは非常に便利です。

    はじめに

    今回は API を利用した非同期処理の基本的な使い方を学ぶために、async await について解説します。特に、Promise との違いや、async await を使った非同期処理の書き方について詳しく説明します。 以前 API を利用した簡易的な Web アプリを作成した際に何気なく使用してしまっていたため、改めてその使い方を理解することにしました。

    非同期処理とは

    そもそも非同期処理とは、ある処理が完了するのを待たずに次の処理を実行することを指します。これにより、時間のかかる処理(例えば、API からのデータ取得など)を待つことなく、他の処理を進めることができます。 まず大前提として Javascript はシングルスレッドで動く言語なため、基本的には一つの動作しか実行できないというのがあります。 そのため、非同期処理を使うことで、時間のかかる処理を待たずに次の処理を実行することができるようになります。

    console.log("A");
    console.log("B");
    console.log("C");

    実際のコードで説明すると上記のコードでは A→B→C の順番で実行されます。 しかし、下記のコードでは setTimeOut の処理はすぐには完了しないため一旦保留され、1 秒後に実行されるため出力としては A→C→B の順番で実行されます。

    console.log("A");
     
    setTimeout(() => {
      console.log("B");
    }, 1000);
     
    console.log("C");

    promise の基本

    Promise は非同期処理の結果を表すオブジェクトで、非同期処理が成功した場合は resolve メソッドが呼ばれ、失敗した場合は reject メソッドが呼ばれます。Promise を使うことで、非同期処理の結果を簡潔に扱うことができます。 Promise の利点としては、非同期処理の結果を簡潔に扱えること、複数の Promise を組み合わせて処理できること、非同期処理中に発生したエラーを 1 箇所で処理することができるなどがあります。

    promise とその限界

    そんな Promise にはいくつか問題点があります。 非同期処理におけるコールバック関数の複雑さ(いわゆるコールバック地獄)を解決するために登場したのが Promise です。 しかし、Promise を使っても非同期処理が複雑になることがあります。特に、複数の非同期処理を連続して実行する場合、Promise チェーンが深くなり、可読性が低下することがあります。 .then()が連続すると一見見やすそうで、複雑になると逆に読みづらくイマイチです。 また、非同期処理が深く連鎖すると、どこでエラーが発生したのか分かりづらくなることがあります。 これを解決するために登場したのが async await です。

    async await の基本

    async とは

    async とは非同期関数を定義する関数宣言のことです。 関数の前にasyncをつけることで、非同期関数を定義することができます。

    await とは

    async function 内で Promise の結果が返されるまで待機する演算子のことです。 関数の前に await を指定することで、Promise の結果が返されるまで待機することができます。

    async await の基本的な使い方

    ここで具体的な例を見てみます。

    function fetchData() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("データ取得完了");
        }, 1000);
      });
    }
     
    async function main() {
      const result = await fetchData();
      console.log(result);
    }

    ポイントとしては await は Promise が解決されるまで待機するということです。

    並列処理

    await を 1 つずつ書くと処理が直列になるため、独立した処理は Promise.all を使って並列処理することができます。

    async function fetchInParallel() {
      const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
      console.log(data1, data2);
    }

    まとめ

    改めて async await の使い方を学ぶことで、普段何気なく使用してた非同期処理についての理解が深まりました。 どのような経緯で async await が登場したのか、Promise の限界についても理解できたので、今後はより適切な方法で非同期処理を行うことができると思います。

    On this page