节点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
声明options
variables。 在JavaScript中,它意味着声明一个全局variables(或node.js
模块范围的variables)。