第9章: 非同期処理とPromise

第9章: 非同期処理とPromise

概要

JavaScriptは基本的にシングルスレッドで実行されるため、長時間かかる処理やI/O待ちの処理を行う際には非同期処理の仕組みが重要になります。ES6で標準化されたPromiseオブジェクトは、非同期処理の完了や失敗を表現するためのオブジェクトです。Promiseを使うと、コールバック関数地獄(いわゆる「Callback Hell」)を回避し、読みやすい非同期コードを書くことができます。

Promiseオブジェクトは最初は「保留(pending)」状態ですが、処理が完了すると「fulfilled(履行)」状態になり結果の値を保持します。エラーが起きれば「rejected(拒否)」状態になりエラー理由を保持します。Promiseには.then()メソッドと.catch()メソッドが用意されており、成功時の処理と失敗時の処理をそれぞれチェーン(連結)して書くことが可能です。

本章では、Promiseの基本的な使い方として、新たにPromiseを作成する方法と、既存の非同期関数から返されるPromiseを扱う方法を学びます。

コードと解説

JavaScriptでPromiseを使用する例を示します。fetchDataという擬似的な非同期関数を作り、1秒後にデータを返すようにしてみます。そのPromiseを.thenで受け取り、結果を処理します。


function fetchData() {
    return new Promise((resolve, reject) => {
        console.log("データ取得中...");
        setTimeout(() => {
            const success = true;  // 成功/失敗を決めるフラグ
            if (success) {
                resolve({ message: "データ取得成功", data: [1, 2, 3] });
            } else {
                reject(new Error("データ取得失敗"));
            }
        }, 1000);
    });
}

// Promiseを利用した非同期処理の実行
fetchData()
    .then(result => {
        console.log(result.message);       // "データ取得成功"
        console.log(result.data);          // [1, 2, 3]
    })
    .catch(error => {
        console.error(error);              // エラー時はこちらが実行される
    })
    .finally(() => {
        console.log("非同期処理が完了しました。");
    });

解説: fetchData関数ではnew Promise(...)を返しています。コンストラクタに渡した関数は「executor(実行者)」と呼ばれ、resolverejectという2つのコールバックを引数に取ります。非同期処理が成功した際にはresolve(結果)を呼び出し、失敗した際にはreject(エラー)を呼び出します。上記ではsetTimeoutで1秒待った後、successフラグに応じて成功ならオブジェクトをresolveし、失敗ならエラーメッセージをrejectしています。

fetchData()の呼び出し側では、返されたPromiseに対して.then()で成功時の処理、.catch()で失敗時の処理、.finally()で最終的に常に行いたい処理を指定しています。.then()の中のresultresolveで渡された値(ここでは{ message: ..., data: ... }オブジェクト)が渡ってきます。一方.catch()errorにはrejectで渡されたErrorオブジェクトが渡ります。.finally()は成功・失敗に関わらず一度だけ実行されるブロックですので、後処理などに利用できます。

なお、Promiseチェーンでは.thenを続けて書くことで非同期処理の結果を次の.thenに渡していくこともできます。例えば.then(result => { return 加工した新しい結果; })のようにreturnすると、新たなPromiseとして次の.thenに渡されます。この仕組みにより、非同期処理を順序立てて書き進めることができます。

目次に戻る