2014-12-31 158 views
0

我想發出一個初始請求來獲取ID列表,然後爲每個單獨的ID發出請求並將JSON結果存儲在一個數組中。下面是代碼基礎:返回請求循環的結果

request(options, function(err, resp, body){ 
ids = (JSON.parse(body))[ids]; 
results=[]; 
for(id in ids){ 
    options.path='/api/example/' + ids[id]; 
    request(options, function(err, resp, body){ 
    results.push(JSON.parse(body)); 
    }) 
} 
res.send(results); 
}) 

當我運行它,結果仍然是一個空數組,當我在內部請求功能把res.send(結果),它僅捕獲一個結果,而不是所有的人。有任何想法嗎?

回答

1

大多數NodeJS操作都是異步的。如果某些功能需要回調這意味着不能保證在調用它之後你會得到結果。

當您使用for循環執行N個請求時,您將啓動N個異步操作,並且在底層異步操作結束時將調用每個回調。

這裏有很多選擇來解決這個問題。

例如,you can use Q,一個Promise pattern實施,排隊異步的承諾,然後等待,直到所有的都得到了解決:

request(options, function(err, resp, body){ 
// First of all, you create a deferred object 
var deferred = Q.defer(); 

// Also, you create an array to push promises 
var promises = []; 

ids = (JSON.parse(body))[ids]; 
results=[]; 
for(id in ids){ 
    options.path='/api/example/' + ids[id]; 

    // You create a promise reference, and later 
    // you add it to the promise array 
    var promise = deferred.promise; 
    promises.push(promise); 

    request(options, function(err, resp, body){ 
    results.push(JSON.parse(body)); 

    // whenever an async operation ends, you resolve its promise 
    deferred.resolve(); 
    }) 
} 

// Now you wait to get all promises resolved (i.e. *done*), and then your 
// "results" array will be filled with the expected results! 
Q.all(promises).then(function() { 
    res.send(results); 
}); 
}); 
+0

感謝您的答覆!當我嘗試這樣做時,它給了我一個TypeError:Object [object Promise]沒有方法'resolve'。 – Keroles

+0

@Keroles它是'deferred.resolve()',對不起。我已經更新了答案中的代碼片段。 –

+0

這工作,我也移動了最後一部分(Q.all ...)以外的主要請求(以及延期和承諾變量),它似乎大多數時間工作(不一致可能與api我是合作)再次感謝您的幫助! – Keroles