节点js没有解析承诺数组

时间:2014-08-14 17:31:02

标签: javascript node.js promise q

我正在尝试执行多个异步请求并尝试使用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');
});

我在这里做错了什么?

苏里亚

3 个答案:

答案 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中的模块范围变量)。