Цепочка произвольного числа обещаний в Q
Я хочу отправить HTTP-запрос N раз. Я хочу в конечном итоге получить информацию о результатах каждого из этих запросов.
Запуск функции запроса один раз прекрасно работает. Вот функция HTTP-запроса с использованием Q.defer():
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(результаты) печатается до того, как я получаю журналы от обратного вызова 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 (в моем исходном примере) в массиве?
2 ответа
Это отвечает на обновленную часть вопроса:
var buildCalls = function() {
var calls = [];
for (var i in stories) {
calls.push(myFunc(i));
}
return calls;
}
return Q.all(buildCalls());
Q имеет другие функции, помогающие в рабочих процессах на основе Promise. Метод, который вам нужно использовать, Q#all
, Если у вас есть массив обещаний, и вы хотите вызвать функцию, когда все они успешно выполнены, вы делаете
Q.all(array_of_promises).then(success_callback, failure_callback);
После того, как все обещания запроса выполнены, success_callback
называется. Если кто-то из них отвергает, failure_callback
называется сразу.