はじめに
この記事はbluebird.jsのPromise.map
とPromise.mapSeries
について、勉強会で取り上げたものです。
1. Promise.mapについて
1-1. 概要
入出力仕様
Promise.map(array, function, options) -> Promise
map
は第1引数で受け取る配列の各要素について、第2引数でそれを引数にとる非同期関数を 『並列に順番に実行して』、実行した全ての非同期関数の完了を待つPromiseを返す。
このPromiseがresolveしたとき、非同期関数の戻り値の結果が**『順番に入った配列』**を返す。ただし 『実行が完了する順番は保証されない』。
つまり・・・
- 結果の順番は保証される
- 実行を開始する順番は保証される
- 実行が完了する順番は保証されない
また、第3引数にconcurrency
プロパティを渡すと、同時に実行する数を制限できる(デフォルトは制限なし)。
1-2. サンプルコード
基本的な例
// 非同期的に2倍する関数
const x2 = num => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * 2), 1000);
});
};
const result = await Promise.map( [1, 2, 3, 4, 5], x2 );
console.log(result);
// -> [2, 4, 6, 8, 10]
実行完了の順番が保証されない例
// 非同期的かつランダムに遅らせて2倍する関数
const x2 = num => {
return new Promise((resolve, reject) => {
const ms = Math.random() * 1000 // ランダムな遅れ
setTimeout(() => {
const res = num * 2;
console.log(res); // コンソール出力(処理完了)
resolve(res);
}, ms);
});
};
const result = await Promise.map( [1, 2, 3, 4, 5], x2 );
console.log(result);
/*
# コンソール出力
> 10
> 6
> 8
> 2
> 4
# ↑のようなときもあれば
# ↓のようなときもある
> 2
> 10
> 4
> 6
> 8
# だけどresultの値は必ず順番通りになる
> [2, 4, 6, 8, 10]
*/
concurrencyで同時に実行する数を制限する例
// 非同期的に2倍する関数
const x2 = num => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * 2), 1000);
});
};
const result = await Promise.map([1, 2, 3, 4, 5], x2, { concurrency: 2 }); // 同時に2つ実行
console.log(result);
/*
# 出力
# 1秒後
> 1
> 2
# さらに1秒後
> 3
> 4
# さらに1秒後
> 5
# resultの値
> [2, 4, 6, 8, 10]
*/
2. Promise.mapSeriesについて
2-1. 概要
入出力仕様
Promise.mapSeries(array, function) -> Promise
mapSeriesは第1引数で受け取る配列の各要素について、第2引数でそれを引数にとる非同期関数を
『直列に順番に実行して』、実行した全ての非同期関数の完了を待つプロミスを返す。
Promise.mapと殆ど同じだが、唯一の違いは**『実行が完了する順番が保証されること』**。また、直列に実行するためconcurrency
プロパティがない。
2-2. サンプルコード
実行完了の順番が保証される例
// 非同期的かつランダムに遅らせて2倍する関数
const x2 = num => {
return new Promise((resolve, reject) => {
const ms = Math.random() * 1000 // ランダムな遅れ
setTimeout(() => {
const res = num * 2;
console.log(res); // コンソール出力(処理完了)
resolve(res);
}, ms);
});
};
const result = await Promise.mapSeries( [1, 2, 3, 4, 5], x2 );
console.log(result);
/*
# 出力
# 直列に実行するため処理が完了する順番が保証される
> 2
> 4
> 6
> 8
> 10
# resultの値
> [2, 4, 6, 8, 10]
*/
3. 最後に
bluebird.js
は便利なヘルパーが多数用意されていてとても便利ですね。非同期処理の実装がとてもラクになります。
Googleで調べるときは検索窓にbluebird.js
と入れることをオススメします。.js
をつけないで検索すると・・・。