異步編程完全是關於鏈接塊。這允許節點高效地運行其事件隊列,同時確保您的步驟按順序完成。例如,下面是從web應用程序我寫了一個查詢:
app.get("/admin", isLoggedIn, isVerified, isAdmin, function (req, res) {
User.count({}, function (err, users) {
if (err) throw err;
User.count({"verified.isVerified" : true}, function (err2, verifiedUsers) {
if (err2) throw err2;
Course.count({}, function (err3, courses) {
// and this continues on and on — the admin page
// has a lot of information on all the documents in the database
})
})
})
})
注意我是如何鏈接的功能,彼此的內部調用。只有在調用User.count({"verified.isVerified" : true}, ...)
時才能調用Course.count({}, ...)
。這意味着I/O永遠不會被阻止,並且在沒有所需信息的情況下永遠不會呈現頁面。
你真的沒有給出關於您的問題足夠的信息(因此有可能是一個更好的辦法來解決它),但我認爲你可以,現在,這樣做:
var request = require('request'),
requests = [],
values = [],
length; // a counter to store the number of times to run the loop
request("url1", function() {
length = Object.keys(list).length;
// referring to the list below;
// make sure list is available at this level of scope
for (var x in list){
requests.push(requestFunction(x));
length--;
if (length == 0) {
async.parallel(requests, function (allResults) {
console.log(values); // prints the values array
});
}
}
}
function requestFunction(x) {
request("url2", function (e,r,b) {
values[i] = b;
return b;
}
}
我假設requestFunction()
需要一段時間才能加載,這就是爲什麼async.parallel
在for (var x in list)
循環完成之前運行的原因。在循環結束後強制async.parallel
運行,您需要一個計數器。
var length = Object.keys(list).length;
這將返回list
關聯數組(關鍵字對象)中的鍵數。現在,每次運行for循環時,都會減少length
。當length == 0
,然後你運行你的async.parallel
過程。
編輯:你也可以寫requests.push()
部分爲:
requests.push(
(function() {
request("url2", function (e,r,b) {
values[i] = b;
return b;
}
})()
);
,我認爲它是多餘的存儲b
兩個values
和requests
,但我一直是你了吧。
這非常有幫助。現在我有一個問題,請求數組是未定義的。我是否在requestFunction中錯誤地返回函數? – CWon
@CWon這是針對特定圖書館的嗎?無論如何,'requestFunction'並沒有什麼意義。你返回一個函數:'return function(callback){...}',但是lambda不返回任何東西。 – royhowie
@CWon我在原來的答案中更改了'requestFunction',並添加了另一個推送到'requests'數組的方法。 – royhowie