6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年2月7日 JavaScript (JS Primer) Promise

Promiseとは

非同期処理の結果を表現するビルトインオブジェクトです。

エラーファーストコールバックを発展させたものです。

異なる点として単なるルールではなくオブジェクトという形にして非同期処理を統一的なインターフェースで扱うことが出来ます。

エラーファーストコールバックの復習

  • 非同期処理が成功した場合は、1番目の引数にnullを渡し2番目以降の引数に結果を渡す
  • 非同期処理が失敗した場合は、1番目の引数にエラーオブジェクトを渡す
// asyncTask関数はエラーファーストコールバックを受け取る
asyncTask((error, result) => {
    if (error) {
        // 非同期処理が失敗したときの処理
    } else {
        // 非同期処理が成功したときの処理
    }
});

エラーファーストコールバックとPromiseの比較

エラーファーストコールバックの特徴

  • 非同期処理が成功した場合は、1番目の引数にnullを渡し2番目以降の引数に結果を渡す
  • 非同期処理が失敗した場合は、1番目の引数にエラーオブジェクトを渡す

Promiseの特徴

  • 非同期処理に成功⇨コールバック関数としてthenメソッドへ渡します。
  • 非同期処理に失敗⇨コールバック関数としてcatchメソッドへ渡します。

Promise.prototype.then() メソッド

then() メソッドは Promiseを返します。最大 2 つの引数として、 Promise が成功した場合と失敗した場合のコールバック関数を取ります。

MDN リファレンス

Promiseインスタンスに対して、成功と失敗時の処理をそれぞれコールバック関数として渡すという形になります。

コード例

// asyncPromiseTask関数はPromiseインスタンスを返す
asyncPromiseTask().then(()=> {
    // 非同期処理が成功したときの処理
}).catch(() => {
    // 非同期処理が失敗したときの処理
});

エラーファーストコールバックと異なる点はPromiseインスタンスを返している点です。

複雑な非同期処理をうまくパターン化できるというのがPromiseの役割であり、 Promiseを使う理由のひとつであると言えます。

thenという記述を見るだけで、前に行った処理が成功した際に行われている処理だということがひと目でわかりますね。

Promiseインスタンスの作成

以下の例では2つの引数を取る関数を定義し、その関数をPromiseインスタンスを初期化する際に渡しています。

const executor = (resolve, reject) => {
    // 非同期の処理が成功したときはresolveを呼ぶ
    // 非同期の処理が失敗したときはrejectを呼ぶ
};
const promise = new Promise(executor);

new演算子に関数を渡さない場合、以下のようにエラーが発生しました。

TypeError: Promise resolver undefined is not a function

thenは2つ引数を取れるため成功した場合と失敗した場合の処理を呼び出すことも出来るということは新しく知りました。

// `Promise`インスタンスを作成
const promise = new Promise((resolve, reject) => {
    // 非同期の処理が成功したときはresolve()を呼ぶ
    // 非同期の処理が失敗したときにはreject()を呼ぶ
});
const onFulfilled = () => {
    console.log("resolveされたときに呼ばれる");
};
const onRejected = () => {
    console.log("rejectされたときに呼ばれる");
};
// `then`メソッドで成功時と失敗時に呼ばれるコールバック関数を登録
promise.then(onFulfilled, onRejected);

then(A).catch(B)として拾えますが、then( A, B )としても書けます。 ここでは第二引数でrefect(失敗したときの処理)を登録しています。

Promiseコンストラクタのresolveとreject、thenメソッドのonFulfilledとonRejectedは次のような関係となります。

  • resolve(成功)したとき⇨onFulfilledが呼ばれる
  • reject(失敗)したとき⇨onRejected が呼ばれる

参考

JS primer Promise

Promise.prototype.then()