第10章: async/await による非同期処理の改善

第10章: async/await による非同期処理の改善

概要

ES2017では、Promiseをさらに扱いやすくするためにasync/await構文が導入されました。async関数の中でawait式を使うと、Promiseの完了を待ってその結果を取得するまで関数の実行を一時停止し、まるで同期処理のように非同期処理を書けます。

asyncを付けた関数は常にPromiseを返すようになります(関数内部で暗黙的にPromiseが生成されます)。awaitはそのPromiseが解決されるまで待ち、解決値を返します。awaitasync関数の中でしか使用できない制約がありますが、その代わりasync関数内では直列的なコードで非同期処理を順序よく書くことが可能です。

本章では、前章で書いたPromiseの例をasync/awaitを用いた書き方に書き換えてみます。

コードと解説

JavaScriptでasync/awaitを使った例を示します。先ほどのfetchData(Promiseを返す関数)をそのまま利用し、async関数内でawaitしています。


async function processData() {
    try {
        console.log("データ取得開始");
        const result = await fetchData();   // fetchData()のPromiseが解決するまで待機
        console.log(result.message);        // "データ取得成功"
        console.log(result.data);           // [1, 2, 3]
        // ここでresultを使った後続の処理が書ける
    } catch (error) {
        console.error("エラーが発生しました:", error);
    } finally {
        console.log("非同期処理が終了(async/await)");
    }
}

processData();  // async関数はPromiseを返すが、ここでは即時実行
                

解説: async function processData()と宣言することで、この関数は必ずPromiseを返すようになります。実際には関数がreturnで値(または何も)返した場合、その値で解決するPromiseが戻り、エラーが発生してcatchされなかった場合はrejectされたPromiseが返ります。await fetchData()の行では、前章で定義したfetchData()の完了を待ち、その結果resultに代入します。awaitしている間、非同期処理が完了するまでprocessData関数の実行は一時停止し、完了後に次の行に進みます。

この間JavaScript全体の実行がブロックされるわけではなく、他のイベントループは回っています。awaitはあくまでprocessData関数内の流れを一時停止するものです。そのため、async/awaitを使っても非同期処理であることに変わりはなく、内部ではPromiseが動いています。

try...catch構文を用いることで、awaitした呼び出しでエラー(Promiseのreject)が発生した場合にcatchブロックで捕捉できます。.then().catch()チェーンの場合と同様に、例外処理を行えるわけです。finallyブロックも用いることができ、Promiseの.finallyと同様の役割を果たします。

このようにasync/awaitを使うことで、Promiseチェーンで書いていた非同期処理をより直感的な手続き型のコードに変換できます。特に複数の非同期処理を順番に行う場合や、条件分岐を交えながら非同期処理を記述する場合に、async/awaitは可読性と保守性を向上させます。

目次に戻る