इससे पहले कि मैं आगे समझाऊं, मैं यह नोट करना चाहूंगा कि आपके कोड में एक बग है:
function(err_positive, result_positive) {
result_positive.count(function(err, count){
console.log("Total matches: " + count);
positives[i] = count; // <--- BUG: i id always 5 because it
}); // is captured in a closure
}
क्लासिक क्लोजर और लूप समस्या। देखें:कृपया लूप में जावास्क्रिप्ट क्लोजर के उपयोग की व्याख्या करें
अब, लूप्स में एसिंक्रोनस फ़ंक्शंस को कैसे हैंडल करें। मूल विचार यह है कि अंतिम कॉल के वापस आने के बाद आपको ट्रैक करना होगा कि कितनी एसिंक्रोनस कॉल पूरी हुई हैं और अपना कोड चलाएं। उदाहरण के लिए:
var END=5;
var counter=end;
for (var i=0;i<END; i++) {
collection.find(
{value:1},
{created_on:
{
$gte:startTime + (i*60*1000 - 30*1000),
$lt: startTime + (i*60*1000 + 30*1000)
}
},
(function(j){
return function(err_positive, result_positive) {
result_positive.count(function(err, count){
console.log("Total matches: " + count);
positives[j] = count;
});
counter--;
if (!counter) {
/*
* Last result, now we have all positives.
*
* Add code that need to process the result here.
*
*/
}
}
})(i)
);
}
हालांकि, अगर हम ऐसा करना जारी रखते हैं तो यह स्पष्ट है कि हम अस्थायी चरों का एक समूह बना लेंगे और अंत में भयानक नेस्टेड कोड के साथ समाप्त हो जाएंगे। लेकिन यह जावास्क्रिप्ट होने के नाते, हम एक फ़ंक्शन में इस पैटर्न के लिए तर्क को समाहित कर सकते हैं। जावास्क्रिप्ट में इस "सभी के लिए प्रतीक्षा करें" तर्क का मेरा कार्यान्वयन यहां दिया गया है:नोड.जेएस में समानांतर निष्पादन का समन्वय करना
लेकिन चूंकि हम node.js का उपयोग कर रहे हैं, हम सुविधाजनक async मॉड्यूल फॉर्म npm का उपयोग कर सकते हैं:https://npmjs .org/package/async
async के साथ, आप अपना कोड इस तरह लिख सकते हैं:
var queries = [];
// Build up queries:
for (var i=0;i <5; i++) {
queries.push((function(j){
return function(callback) {
collection.find(
{value:1},
{created_on:
{
$gte:startTime + (j*60*1000 - 30*1000),
$lt: startTime + (j*60*1000 + 30*1000)
}
},
function(err_positive, result_positive) {
result_positive.count(function(err, count){
console.log("Total matches: " + count);
positives[j] = count;
callback();
});
}
);
}
})(i));
queries.push((function(j){
return function(callback) {
collection.find(
{value:0},
{created_on:
{
$gte:startTime + (j*60*1000 - 30*1000),
$lt: startTime + (j*60*1000 + 30*1000)
}
},
function(err_negative, result_negative) {
result_negative.count(function(err, count){
console.log("Total matches: " + count);
negatives[j] = count;
callback();
});
}
);
}
})(i));
}
// Now execute the queries:
async.parallel(queries, function(){
// This function executes after all the queries have returned
// So we have access to the completed positives and negatives:
// For example, we can dump the arrays in Firebug:
console.log(positives,negatives);
});