6

我想发送一个 HTTP 请求 N 次。我希望最终获得有关每个请求结果的信息。

运行请求功能一次效果很好。这是使用 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 之后的成功回调中”)。但是,console.log(results) 在我从 runRequest().then() 回调获取日志之前打印,它是一个空数组。

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

谢谢!

更新 后续问题以响应@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(在我的原始示例中)的动态调用次数的任何提示?

4

2 回答 2

7

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

var buildCalls = function() {

  var calls = [];
  for (var i in stories) {

    calls.push(myFunc(i));
  }
  return calls;
}

return Q.all(buildCalls());
于 2013-07-16T23:11:35.090 回答
5

Q 具有其他功能来帮助基于 Promise 的工作流程。您需要使用的方法是Q#all. 如果您有一系列承诺,并且您想在所有承诺都成功实现后调用一个函数,您可以

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

在所有请求承诺都实现后,success_callback被调用。如果其中任何一个拒绝,failure_callback则立即调用。

于 2013-06-07T05:10:57.207 回答