我正在尝试执行多个异步请求并尝试使用promises获取输出。
如果我有多个请求排队,Q.all(promises).then()函数似乎不起作用。对于单个请求,承诺都已解决。示例代码在这里。
var request = require('request');
var Q = require('q');
var sites = ['http://www.google.com', 'http://www.example.com', 'http://www.yahoo.com'];
// var sites = ['http://www.google.com']
var promises = [];
for (site in sites) {
var deferred = Q.defer();
promises.push(deferred.promise);
options = {url: sites[site]};
request(options, function (error, msg, body) {
if (error) {
deferred.reject();
}
deferred.resolve();
});
}
Q.all(promises).then (function () {
console.log('All Done');
});
我在这里做错了什么?
苏里亚
答案 0 :(得分:3)
这是我在场景中所做的,这是整个代码:
var Q = require('q');
var request = Q.nfbind(require('request'));
var sites = ['http://www.google.com', 'http://www.example.com', 'http://www.yahoo.com'];
var requests = sites.map(request);
Q.all(requests).then(function(results){
console.log("All done") // you can access the results of the requests here
});
现在为什么:
.map
比手动迭代它们更容易,因为我们在这里只为每个URL生成一个操作。此解决方案也很短,需要最少的嵌套。
答案 1 :(得分:0)
不要使用for..in
来迭代数组。这实际上做的是将site
设置为0, 1, 2
,但这并不能很好地发挥作用。使用其他形式的迭代,如常规for
循环或Array.prototype.forEach
sites.forEach(function (site) {
var deferred = Q.defer();
promises.push(deferred.promise);
options = {url: site};
答案 2 :(得分:0)
问题是,您要在deferred
循环的每个刻度上更改for
的值。因此,在您的示例中实际解决的唯一承诺是最后一个。
要修复它,您应该在某些上下文中存储deferred
的值。最简单的方法是使用Array.prototype.forEach()
method代替for
循环:
sites.forEach(function (site){
var deferred = Q.defer();
var options = {url: sites[site]};
promises.push(deferred.promise);
request(options, function (error, msg, body) {
if (error) {
deferred.reject();
}
deferred.resolve();
});
})
您还错过了var
声明options
变量。在JavaScript中,它表示声明全局变量(或node.js
中的模块范围变量)。