在http数组上调用done.在Node.js中获取请求
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);
});
});
我敢肯定,这只是我没有把我的头围绕整个异步性质的节点正确,但有什么明显的其他人吗?
我已经搜索了关于使用http与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
期望一个承诺数组。
Q.nfcall
只是周围的糖
处理使用Node.js回调模式的函数,其中回调的形式为function(err, result)
https://github.com/kriskowal/q adapting-node
您应该始终在尽可能低的级别执行约定。这使得对并发性的推理容易得多。
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);
});
});
可以通过使用Bluebird等更好的promise库进一步缩短。
你也可以使用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
});
相关文章:
- 如何使用 Node JS 获取 JSON 嵌套数组值
- Undercore.js获取对象数组中键对象的值
- 使用moment.js获取时间分区的偏移日期对象
- js-获取带有变量的json
- Vue.js获取组件中的一个元素
- 使用Pebble.js获取AJAX请求时出错
- 使用node.js获取外部网站内容
- 使用moment.js获取月份和年份中的所有日期
- Ember.js-获取DOM元素的模型数据
- 如何使用moment.js获取24小时内日期之间的时差
- 如何使用moment.js获取日期和时间
- 节点.js获取HTTP_USER_AGENT并阻止HTTrack
- 从mixin Vue.js获取数据
- 使用PDF.js获取PDF的修剪区域
- JS获取文件内容
- 限制Backbone.js获取的数据量()'es
- 使用Passport.js获取路由之外的当前用户
- 用ajax用js获取php
- 使用moment.js获取月底前的剩余天数
- 通过Crypto.js获取文件的md5sum