节点js不解决承诺的数组

我试图执行几个asynchronous请求,并试图使用承诺获得输出。

如果我有多个请求排队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'); }); 

我在这里做错了什么?

苏里亚

这是我在场景中做的,这是整个代码:

 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 }); 

现在为什么:

  • 总是在尽可能最低的水平promisify,promisited请求本身,而不是speicific请求。 首选自动promisification手动promisification不会犯愚蠢的错误。
  • 处理集合时 – 使用.map比手动迭代更容易,因为我们在这里每个URL只产生一个动作。

此解决scheme也很短,只需要最less的嵌套。

不要使用for..in遍历数组。 这实际上是把site设置为0, 1, 2这只是不工作得很好。 使用一些其他forms的迭代,如普通循环,或Array.prototype.forEach

 sites.forEach(function (site) { var deferred = Q.defer(); promises.push(deferred.promise); options = {url: site}; 

问题在于你正在改变for循环中每个tick的deferred值。 所以,在你的例子中实际解决的唯一的承诺是最后一个。

要修复它,你应该在某些情况下存储deferred的值。 最简单的方法是使用Array.prototype.forEach()方法而不是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声明optionsvariables。 在JavaScript中,它意味着声明一个全局variables(或node.js模块范围的variables)。