概要
タイトルの通り。
Javascriptで配列に詰めたパラメータを1つずつ、ajaxなどの非同期処理を含む関数に渡して実行する場合
なにもしないと並列(配列に入ってる分、ajax関数が同時実行)で実行されます。
サーバ負荷などの考慮で、これを並列でなく逐次(同時に実行する処理が1つずつだけ)にする方法です。
es2016
とかであれば async
await
を使うと簡単です。
今回はあえてPromiseを使う方法の紹介です。
aws Lambda
のnodeを使っていたらasync
と arrow Functionの組み合わせで
文法エラーになってしまっていたのでPromiseを引っ張り出してきました。
調べたらnode7.6からasyncとawaitが標準でサポートされた模様
例1
配列分、thenの連鎖を作っておく方法
@mpyw さんにコメント頂いた方法
すっきり書けるのでこっちの方が好みです。ありがとうございます。
const resolveAfter = (args) => {
return new Promise((resolve) => {
console.log(args);
setTimeout(resolve, 1000);
});
};
const argsList = [
{ id: 1, name: 'taro' },
{ id: 2, name: 'jiro' },
{ id: 3, name: 'saburo' }
];
let p = Promise.resolve();
argsList.forEach((args) => {
p = p.then(() => resolveAfter(args));
});
イメージとしては
- 非同期処理を含む関数(でPromiseされてないもの)はPromiseで括る
- パラメタを配列に入れ、forEach等で回す(処理順を確保)
- 再代入するpを定義、pに配列分非同期処理のthenの連鎖を詰める感じ
例2
reduceを使う方法
letはちょっと・・・な人はこちら
argsList.reduce((current, args) => {
return current.then(() => {
return resolveAfter(args);
});
}, Promise.resolve());
イメージとしては
- 非同期処理を含む関数(でPromiseされてないもの)はPromiseで括る
- パラメタを配列に入れ、reduceで回す(処理順を確保)
- reduceのinitialに
Promise.resolve()
を入れることでPromiseObjectが入る- これによりreduceのiterateの都度、Promise.thenされるようになる
- reduceを使うことで1つ前のpromiseオブジェクトを取得できるのでそれを利用した方法