在Q中链接任意数量的承诺

我想发送一个HTTP请求N次。 我想最终得到关于每个请求的结果的信息。

运行请求function一次很好。 以下是使用Q.defer()的HTTP请求函数:

function runRequest() { var deferred = Q.defer(), start = (new Date).getTime(), req = HTTP.request(options, function(res) { var end = (new Date).getTime(), requestDetails = { reqStatus: res.statusCode, reqStart: start, reqEnd: end, duration: end - start } deferred.resolve(requestDetails); }); req.on('error', function(e) { deferred.reject(e.message); }); req.end(); return deferred.promise; } 

如果我这样做,我收回我期望的数据:

 runRequest().then(function(requestDetails) { console.log('STATUS: ' + requestDetails.reqStatus); console.log('Duration: ' + requestDetails.duration); console.log('Start: ' + requestDetails.reqStart); console.log('End: ' + requestDetails.reqEnd); }, function(error) { console.log('Problem with request: ' + error); }) .done(); 

为了迭代,我试图把它放到for循环中:

 function iterateRequests() { var deferred = Q.defer(); var reqResults = []; for (var iteration = 0; iteration < requests; iteration++) { runRequest() .then(function(requestDetails) { console.log('STATUS: ' + requestDetails.reqStatus); reqResults.push(requestDetails); }, function(error) { console.log('Problem with request: ' + error); }); } deferred.resolve(reqResults); return deferred.promise; } 

然后我这样称呼它:

 iterateRequests() .then(function(results) { console.log(results); console.log("in the success callback after iterateRequests"); }, function() { console.log("in the failure callback after iterateRequests"); }) .done(); 

我最终进入成功callback(即,它在iterateRequests后成功callback“)。 但是,console.log(results)在我从runRequest()。then()callback获得日志之前打印,它是一个空数组。

链接/迭代promise返回函数的任何想法或一些指导?

谢谢!

更新后续问题回复@ abject_error的答案:

检出Q.all。 绝对看起来像我所需要的。 和我一起工作的事情要简单得多。 我做了一个简单的testing用例来帮助我弄清楚它是如何工作的:

 var Q = require("q"); function returner(number) { var deferred = Q.defer(); deferred.resolve(number); return deferred.promise; } function parent() { return Q.all([ returner(1), returner(2), returner(4) ]); } parent() .then(function(promises) { // works - promises gives me [1, 2, 4] console.log(promises); }); 

所以我看到如果我事先知道我需要调用它的次数(以及我要调用的函数),我该如何使用它。 有关如何获得dynamic数量的调用返回(在这个例子中)或runRequest(在我的原始示例)在数组中的任何提示?

这回答了问题的更新部分:

 var buildCalls = function() { var calls = []; for (var i in stories) { calls.push(myFunc(i)); } return calls; } return Q.all(buildCalls()); 

Q还有其他的function来帮助基于Promise的工作stream程。 你需要使用的方法是Q#all 。 如果你有一系列的承诺,并且你想在所有的都成功实现的时候调用一个函数,你可以这么做

Q.all(array_of_promises).then(success_callback, failure_callback);

在所有请求承诺完成之后,调用success_callback 。 如果其中任何一个拒绝,则立即调用failure_callback