繁体   English   中英

在Node.js中对一系列http.get请求的调用已完成

[英]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)

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

通过使用更好的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM