मैं आपके द्वारा अपने प्रश्न में सुझाए गए मार्ग पर जाऊंगा और आपके फ़ेचिंग फ़ंक्शन में एक कस्टम कॉलबैक संलग्न करूंगा:
function getStudentsData(callback) {
var setList = [];
var dataList = [];
redisClient.smembers("student_setList", function(err,result) {
setList = result; //id's of students
for(var i = 0; i < setList.length; i++) {
redisClient.get(setList[i], function(err, result) {
if(err) {
console.log("Error: "+err);
} else {
tempObject = JSON.parse(result);
if(tempObject.name != null) {
dataList.push(tempObject);
}
}
});
}
if(dataList.length == setList.length) {
if(typeof callback == "function") {
callback(dataList);
}
console.log("getStudentsData: done");
} else {
console.log("getStudentsData: length mistmach");
}
});
}
getStudentsData(function(dataList) {
console.log("Goes here after checking every single object");
console.log(dataList.length);
//More code here
});
यह शायद सबसे कारगर तरीका है; वैकल्पिक रूप से आप एक पुराने स्कूल पर भरोसा कर सकते हैं while
डेटा तैयार होने तक लूप करें:
var finalList = [];
var list = [0];
redisClient.smembers("student_list", function(err,result) {
list = result; //id's of students
var possibleStudents = [];
for(var i = 0; i < list.length; i++) {
redisClient.get(list[i], function(err, result) {
if(err) {
console.log("Error: "+err);
} else {
tempObject = JSON.parse(result);
if(tempObject.name != null) {
finalList.push(tempObject);
}
}
});
}
});
process.nextTick(function() {
if(finalList.length == list.length) {
//Done
console.log("Goes here after checking every single object");
console.log(dataList.length);
//More code here
} else {
//Not done, keep looping
process.nextTick(arguments.callee);
}
});
हम process.nextTick
. का उपयोग करते हैं वास्तविक while
. के बजाय यह सुनिश्चित करने के लिए कि इस दौरान अन्य अनुरोध अवरुद्ध नहीं हैं; जावास्क्रिप्ट की सिंगल थ्रेडेड प्रकृति के कारण यह पसंदीदा तरीका है। मैं इसे पूर्णता के लिए फेंक रहा हूं, लेकिन पूर्व विधि अधिक कुशल है और नोड.जेएस के साथ बेहतर फिट बैठती है, इसलिए इसके लिए तब तक जाएं जब तक कि एक प्रमुख पुनर्लेखन शामिल न हो।
यह कुछ भी नहीं है कि दोनों मामले एसिंक कॉलबैक पर भरोसा करते हैं, जिसका अर्थ है कि इसके बाहर कोई भी कोड अभी भी दूसरों के काम करने से पहले संभावित रूप से चल सकता है। उदा., हमारे पहले स्निपेट का उपयोग करना:
function getStudentsData(callback) {
//[...]
}
getStudentsData(function(dataList) {
//[...]
});
console.log("hello world");
हमारे कॉलबैक को getStudentsData को फ़ायर करने से पहले वह अंतिम कंसोल.लॉग लगभग चलने की गारंटी है। समाधान? इसके लिए डिज़ाइन करें, बस नोड.जेएस कैसे काम करता है। ऊपर हमारे मामले में यह आसान है, हम केवल console.log को कॉल करेंगे केवल हमारे कॉलबैक में getStudentsData को पास किया गया और इसके बाहर नहीं। अन्य परिदृश्यों में ऐसे समाधानों की आवश्यकता होती है जो पारंपरिक प्रक्रियात्मक कोडिंग से थोड़ा अधिक हटते हैं, लेकिन एक बार जब आप इसके चारों ओर अपना दिमाग लगा लेते हैं, तो आप पाएंगे कि घटना-चालित और गैर-अवरुद्ध होना वास्तव में एक बहुत शक्तिशाली विशेषता है।