JobRequest.findByJobId
は非同期操作です。 JavaScriptで非同期操作をブロックすることはできませんので、手動でカウントすることで同期する必要があります。例(簡略化のために省略エラー処理):
var results = [];
var pendingJobCount = ids.length;
_.forEach(ids, function(id) {
JobRequest.findByJobId(id, function(err, result) {
results.push(result);
if (--pendingJobCount === 0) callback(null, results);
});
});
ありますが、もちろん、ラッパーはこのようなものを行うために構築し、私はそれが実際にどのように動作するかを説明することを好みます。 promisesと呼ばれるラッパーの詳細については、dfsq's answerを参照してください。
また、非同期操作が順不同で完了することがあります。配列results
の順序は、配列ids
の順序と必ずしも一致しません。あなたは情報が接続されていることを必要とする場合は、代わりに、配列のマップで結果を収集することによって、例えば、それを自分で追跡する必要があります:
var results = {};
var pendingJobCount = ids.length;
_.forEach(ids, function(id) {
JobRequest.findByJobId(id, function(err, result) {
results[id] = result;
if (--pendingJobCount === 0) callback(null, results);
});
});
この例では、あなたのids
配列内の重複しないことを前提としています。重複キーの結果は無効になります。
エラー処理は、結果に追加情報を挿入することによって同様に機能します。別の例:あなたは、潜在的に処理する必要があること、
var promises = ids.map(function(id) {
return new Promise(function(resolve, reject) {
JobRequest.findByJobId(id, function (err, result) {
if (err) reject(err);
resolve(result);
});
});
});
Promise.all(promises).then(function(jobs) {
callback(null, jobs);
}, callback);
// or shorter: Promise.all(promises).then(callback.bind(null, null), callback);
注:
results.push({id: id, error: null, value: result});
'async.map 'を使用してください。 – SLaks