调用Node.js中的http.get请求数组

我有一个URL的数组,我使用for循环来调用http.get请求。 由于这是一个asynchronous过程,所以我希望在所有请求都返回后调用完成。

这是我目前的尝试:

grunt.registerTask('verify', function() { var done = this.async(); var promises = []; var urlPrefix = 'http://example.com/'; for(var i = 0; i < deployableFiles.length; i++) { (function(i) { var deferred = Q.defer(); promises.push(deferred); var file = deployableFiles[i]; var path = file.filetype + '/' + getVersionedFileName(file.basename, file.filetype); http.get(urlPrefix + path, function(res) { deferred.resolve(); if(res.statusCode === 200) { grunt.log.oklns(path + ' was found on production server.'); } else { grunt.log.error('Error! ' + path + ' was not found on production server!'); } }).on('error', function(e) { grunt.log.error("Got error: " + e.message); done(); }); })(i); } Q.all(promises) .done(function() { // Everything executed correctly return done(); }, function(reason) { // There was an error somewhere return done(false); }); }); 

我相信这只是我没有正确地包围节点的整个asynchronous性质的头,但有什么明显的其他人?

我已经search了与Q库使用http,似乎可能需要使用Q.nfcall才能使其工作。 我只是很难看到为什么我必须这样做。 (我并不是不喜欢这样做,我比其他任何事情都好奇)

谢谢!

你应该始终在尽可能最低的水平进行promisification。 这使得关于并发的推理变得更容易。

 function getPing(url){ return new Q.Promise(function(resolve,reject){ http.get(url,function(res){ // note this will _not_ wait for the whole request // but just the headers. if(res.statusCode === 200) resolve(); else reject(); }); }); } 

这会让你做:

 grunt.registerTask('verify', function() { var done = this.async(); var urlPrefix = 'http://example.com/'; var pings = deployableFiles.map(function(file){ var path = file.filetype + '/' + getVersionedFileName(file.basename, file.filetype); return getPing(urlPrefix + path); }); Q.all(pings).then(done).catch(function(reason) { // There was an error somewhere // this will happen as soon as _one_ promise rejected return done(false); }); }); 

这可以通过使用更好的承诺库如蓝鸟进一步缩短。

如果这不是拼写错误, promises.push(deferred)应该被推送promises.push(deferred.promise)

 function foo() { ... return defer.promise; } // => foo().then(function() ...); Q.all([ foo(), foo(), ... ]).done(function() ...); 

Q.all期待一系列的承诺。 https://github.com/kriskowal/q#combination


Q.nfcall只是糖,如果

处理使用Node.jscallback模式的函数 ,其中callback函数的forms(err,result)

https://github.com/kriskowal/q#adapting-node

你也可以用async来做到这一点:

 var urlPrefix = 'http://example.com/'; async.each(deployableFiles, function(file, cb) { var path = file.filetype + '/' + getVersionedFileName(file.basename, file.filetype); http.get(urlPrefix + path, function(res) { if (res.statusCode === 200) grunt.log.oklns(path + ' was found on production server.'); else grunt.log.error('Error! ' + path + ' was not found on production server!'); cb(); }).on('error', function(e) { grunt.log.error("Got error: " + e.message); cb(e); }); }, function(err) { // all done if (err) throw err; // all successful });