【非同期処理】Promiseをforループで使う時の書き方を解説【JavaScript】

【非同期処理】Promiseをforループで使う時の書き方を解説【JavaScript】
                 
最終更新日から90日以上経過しています。

JavaScriptで非同期処理を行う場合に必須となるPromise。

ES2017ではasync/await構文により非同期処理が書きやすくなってきていますが、

それ以前ではPromiseのメソッドチェーンで頑張る必要があります。

少しずつ慣れてきたものの、ループが絡むと「どうやって書くんだっけ?」となるので、まとめてみます。

端的に言うとPromiseオブジェクトを配列につめてPromise.allする、という事になります。

 

普通のPromise処理

非同期処理1回だけ実行する場合など、単純な場合はこれで良い。

2回以上続ける場合も.thenをつなげて行けばOK。

尚、チェーンの中で発生したエラーは.catchで拾える。

// asyncFuncは非同期処理。Promiseオブジェクトを返却する。
asyncFunc()
    .then(function(response) {
        /* asyncFuncからの戻り値を使用する処理
        ・
        ・
        ・
        */
    })
    .catch(function(error) {
        /* asyncFuncでエラーになった場合の処理
        ・
        ・
        ・
        */
    });

Promiseをループ処理する場合

1個目のthen節でPromiseをループ処理している。

asyncFunc2から返されるPromiseオブジェクトをpromisesに格納していき、
Promise.allにpromisesを引数として渡す事で、forループが終了するまで後続処理の実行を待機する。

2個目のthen節でPromiseをループ処理した結果が引数で渡されるので、
1つずつ好きなように処理すればOK。

// asyncFunc1は非同期処理。Promiseオブジェクトを返却する。
asyncFunc1()
    .then(function(response) {
        const promises = [];
        // asyncFunc2を10回実行し、終了次第、次の処理へ。
        for (var i=0; i<10; i++) {
            // asyncFunc2も非同期処理。Promiseオブジェクトを返却する。
            // 返却されたPromiseオブジェクトはpromisesに格納されていく。
            promises.push(asyncFunc2());
        };

        return Promise.all(promises);
    })
    .then(function(response) {
        response.forEach(function(value) {
            /* asyncFunc2を10回実行した結果が配列で返されるので、
                ループ等で取り出して使用する。
                尚、配列内の順番は、実行した順になる。
            ・
            ・
            ・
            */
        });
    })
    .catch(function(error) {
        /* asyncFuncでエラーになった場合の処理
        ・
        ・
        ・
        */
    });

おわりに

1つでも resolve()、またはreject()された時に発火するPromise.race()もあるが、
効果的な使用場面が思い浮かばない・・・。

また、冒頭でも触れましたが、ES2017でasync/awaitが追加され、さらに簡潔に非同期処理が記載できるようになったとのこと。
こちらについてはまだ触れられていないので、勉強したら書きます。

JavaScript(TypeScript)カテゴリの最新記事