はじめに
配列のforEach
やmap
は非同期処理をawait
することができない。
自前で同期処理を作る必要がある。
なので配列の非同期処理を同期させる関数forEachSync
とmapSync
を作ってみた。
GitHubで公開中
使い方
forEachSync
await arr.forEachSync(async function callback(currentValue [, index [, array]])[, batchSize]);
mapSync
var new_array = await arr.mapSync(async function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, batchSize]);
batchSize
は1度に並行処理させたい配列の大きさを指定する。
batchSize
は省略可能で省略したら1になる。
サンプルプログラム
forEachSync
var sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
(async () => {
await ary.forEachSync(async (a, index, array) => {
console.log("forEachSync first", a, index, array.length);
await sleep(1000);
}, 3);
console.log("forEachSync end");
})();
batchSize
が3で[1,2,3]
、[4,5,6]
、[7,8,9]
、[10]
と逐次処理される。
mapSync
var sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
(async () => {
var ary_result = await (await ary.mapSync(async (a, index, array) => {
console.log("mapSync first", a, index, array.length);
await sleep(500);
return a + 10;
}, 3)).mapSync(async (a, index, array) => {
console.log("mapSync second", a, index, array.length);
await sleep(500);
return a + 100;
});
console.log("mapSync", ary_result);
})();
mapSync firstはbatchSize
が3で[1,2,3]
、[4,5,6]
、[7,8,9]
、[10]
と逐次処理される。
mapSync secondはbatchSize
が1で[11]
、[12]
、[13]
、[14]
、[15]
、[16]
、[17]
、[18]
、[19]
、[20]
と逐次処理される。
p-map
p-map - npmを見つけた。
mapSyncとほとんど同じプログラムだ。
p-mapのconcurrencyはmapSyncのbatchSizeと同じ。
ぱっと違いを調べたところ
- mapSyncは配列のみだがp-mapはiteratorを受け取るようだ。
- mapSyncは配列のprototypeを書き換えており配列をつなげて使えるが、p-mapは引数を渡す方式で配列をつなげて使えない。
- p-mapはmapper(element, index)だが、mapSyncはcallback(currentValue[, index[, array]])となっておりarrayにも対応。
- mapSyncはawaitすることしか考えていなかったが、p-mapはPromise.catch(reject)に対応しているようだ。
- p-mapはrequire('aggregate-error')と書いてあってNode.js以外ではそのまま使えないが、mapSyncはNode.js以外でもそのまま使える。
- mapSyncのbatchSizeはデフォルト1だが、p-mapのconcurrencyはデフォルトInfinity。
- p-なんとかのnpmが46個もあった。
- forEachSyncに対応するp-eachは作ってないようだ。p-each-seriesはあった。