我想发送N次HTTP请求。我想最终获得有关每个请求结果的信息。
运行请求函数一次很有效。这是使用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();
我最终进入成功回调(即,它在“iterateRequests之后的成功回调”中记录)。但是,在我从runRequest()。then()回调获取日志之前打印了console.log(结果),它是一个空数组。
关于链接/迭代promise-return函数的任何想法或一些指导?
谢谢!
更新 跟进问题以回应@ abject_error的回答:
检查了Q.all。绝对看起来像我需要的。而且我正在使用的东西要简单得多。我做了一个简单的测试用例来帮助我弄清楚它是如何工作的:
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);
});
所以,如果我事先知道需要调用它的次数(以及我要调用的函数),我就知道如何使用它。关于如何在数组中获得对返回者(在此示例中)或runRequest(在我的原始示例中)的动态调用次数的任何提示?
答案 0 :(得分:7)
这回答了问题的更新部分:
var buildCalls = function() {
var calls = [];
for (var i in stories) {
calls.push(myFunc(i));
}
return calls;
}
return Q.all(buildCalls());
答案 1 :(得分:5)
Q还有其他功能来帮助基于Promise的工作流程。您需要使用的方法是Q#all
。如果您有一系列承诺,并且想要在所有成功完成后调用函数,那么您可以
Q.all(array_of_promises).then(success_callback, failure_callback);
在完成所有请求承诺后,将调用success_callback
。如果任何拒绝,则会立即调用failure_callback
。