JavaScriptで非同期処理を行う場合に必須となるPromise。
ES2017ではasync/await構文により非同期処理が書きやすくなってきていますが、
それ以前ではPromiseのメソッドチェーンで頑張る必要があります。
少しずつ慣れてきたものの、ループが絡むと「どうやって書くんだっけ?」となるので、まとめてみます。
端的に言うとPromiseオブジェクトを配列につめてPromise.allする、という事になります。
Promiseのメソッドチェーンをasync/awaitで書き直してみました。
jQuery UIのダイアログを使用した際のPromiseを使用した書き方も書きました。
普通の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が追加され、さらに簡潔に非同期処理が記載できるようになったとのこと。
こちらについてはまだ触れられていないので、勉強したら書きます。

