我會去你在你的問題建議的路線,並附上自定義回調到您的抓取功能:
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
以確保其它請求在此期間不被堵塞;由於Javascript的單線程特性,這是首選的方式。爲了完整起見,我拋出了這一點,但前一種方法更高效,並且與node.js更合適,所以除非涉及重大重寫,否則請儘量去做。
這兩種情況都依賴異步回調,這意味着任何代碼之外的代碼仍然可能在別人完成之前運行。例如,使用我們的第一個片段:
function getStudentsData(callback) {
//[...]
}
getStudentsData(function(dataList) {
//[...]
});
console.log("hello world");
這最後的console.log幾乎可以保證我們的回調傳遞給getStudentsData被炒魷魚之前運行。解決方法?爲它設計,它就是node.js的工作原理。在我們上面的例子中,很容易,我們只需要在我們的回調函數中調用console.log 只有傳遞給getStudentsData,而不是在它之外。其他場景需要的解決方案與傳統的程序編碼有些分離,但是一旦你開始瞭解它,你會發現事件驅動和非阻塞實際上是一個非常強大的功能。
似乎第一個例子並不爲我工作:(參見[這](https://i.gyazo.com/129b071f39bbd1a1c491638be634b00c.png),Redis的調用是異步的。我的'results'的控制檯日誌將首先顯示,因爲它與您的示例中的邏輯完全相同,嗯。 –