[英]Calling done on an array of http.get requests in Node.js
我有一个URL数组,正在使用for循环来调用http.get请求。 由于这是一个异步过程,因此我想在所有请求返回后调用完成。
这是我目前的尝试:
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);
});
});
我敢肯定,这只是我没有正确地围绕节点的整个异步特性来缠绕我的头,但是对其他人来说,有什么明显的东西吗?
我搜索了有关将Q与Q库一起使用的信息,看来可能需要使用Q.nfcall才能使其正常工作。 我只是很难知道为什么要这么做。 (我并不反对这样做,我比其他任何东西都更好奇)
谢谢!
如果这不是拼写错误,应将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.js回调模式的函数 ,其中回调形式为function(err,result)
您应该始终在可能的最低级别上执行承诺。 这使得并发推理变得容易得多。
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);
});
});
通过使用更好的Promise库(如Bluebird),可以进一步缩短此时间。
您也可以使用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
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.