for (var i = 0; i < takusan; i++) {
omotai(i, function () {
おやっ?
});
}
これコールバックの中のものどうやって取るんだ?(だいたい無理)
Promiseが使える環境なら、迷わず書けます。
予めPromise化しておくと便利です。bluebirdなどPromise化を助けてくれるライブラリを使うのもいいでしょう。
function omotaiPromise(arg) {
new Promise(function (resolve, reject) {
omotai(arg, function (err, result) {
if (err != null) {
reject(err);
return;
}
resolve(result);
});
});
}
で、こう。
var promises = [];
for (var i = 0; i < takusan; i++) {
promises.push(omotaiPromise(i));
}
Promise.all(promises)
.then(function (results) {
// results配列の各要素で結果が取れる
});
Promise.allを使うのがキモですね。
別のケース
for (var i = 0; i < list.length; i++) {
if (list[i].conditionSync() === 'good') {
list[i].workHardSync();
}
}
これを非同期化する場合はどうでしょう。
まあまずfilterとかforEachとか使えって話ですね。
list.filter(function (x) { return x.conditionSync() === 'good'; })
.forEach(function (x) { x.workHardSync(); });
で、これのPromise版
Promise
.all(list.map(function (x) { return x.condition(); }))
.then(function (conds) {
Promise.all(
list.filter(function (v, i) { return conds[i]; })
.map(function (x) { return x.workHard(); }));
listがかっちりしていればmapが大活躍します。
functionだらけでみにくいですね。Promiseを使うときはTypeScriptやbabelを使うと良いでしょう。
Promise
.all(list.map(x => x.condition()))
.then(conds =>
Promise.all(
list.filter((v, i) => conds[i])
.map(x => x.workHard()));
ね、簡単でしょう?