【问题标题】:Executing multiple HTTP requests sequentially using async.js使用 async.js 顺序执行多个 HTTP 请求
【发布时间】:2017-11-02 23:56:00
【问题描述】:

如何使用 async.js 顺序执行多个 HTTP 请求。我检查了 async.js 文档,但不知道该怎么做。我想使用 async.js 回调样式实现与以下代码相同的功能。

var http = require('http');
var Q = require('q');
var URL="http://localhost:3000";

var getPromise=function(url) {  
  var deferred  = Q.defer();
  var req = http.get(url, function(response) {
    if(response.statusCode < 200 || response.statusCode > 299){
            deferred.reject(new Error('ErrorCode '+response.statusCode))
        }   
      var result="";
        response.on('data',function(chunk){result +=chunk;} )
        response.on('end',function(){deferred.resolve(result);} ) 
  });

  req.on('error',function(err){
      console.error('Error with the request:', err.message); 
      deferred.reject(err); 
  });

  req.end();  
  return deferred.promise;
} 


getPromise('http://localhost:3000/olympic/2016/ranking/4')
      .then(function(data){
         console.log("Response 1 "+data)
         return getPromise(URL+'/iso/country/'+JSON.parse(data).Country);
      })
      .then(function(data){
         console.log("Response 2 "+data)
         return getPromise(URL+'/olympic/2016/medal/'+JSON.parse(data).iso);
      })
      .then(function(data){
        console.log("Response 3 "+data)
      })
      .catch(function(err){
         console.log(err)
      });

【问题讨论】:

  • 顺序上和 async.js 似乎截然相反。
  • 与到目前为止的答案相反,您似乎想在当前呼叫中使用上一个呼叫的响应。考虑使用async.seqcaolan.github.io/async/docs.html#seq
  • 我没有使用过 Promise,所以不能 100% 确定它们是如何工作的,但是每个 .then 是否使用前一个 Promise 返回的值,还是它们都是单独的调用?
  • @ScottMarcus 我们不应该有时需要先前 HTTP 请求的结果来完成并传递响应以进行另一个 HTTP 调用。我不认为异步和顺序执行是完全相反的事情。
  • 您所描述的有点同步过程,这与异步相反。是的,有时我们确实想要这样,但这就是 JavaScript 默认运行的方式。标准 AJAX 调用和 JavaScript 承诺是为了做你想做的事。

标签: javascript node.js callback async.js


【解决方案1】:

我明白了,我需要 async.waterfall 它需要一组函数并一个一个地执行它们。我们也可以将上一个函数执行的结果传递给下一个函数

var async =  require('async');

async.waterfall([

  function task1(done) {
    console.log('start!');
    setTimeout(function(){
        console.log("T1 Complete"); 
        // <- set value to passed to step 2
        done(null, 'Value from step 1'); 
     },5000);

  },
  function task2(task1Result, done) {
    console.log(task1Result);
    setTimeout(function(){
        console.log("T2 Complete");
        // <- set value to passed to step 3
        done(null, 'Value from step 2');
      },1000);

  },
  function task3 (task2Result, done) {
    console.log(task2Result);
    setTimeout(function(){
        console.log("T3 Complete"); 
        // <- no value set for the next step.
        done(null); 
    },100);

  }
],
function (err) {
  if (err) {
    throw new Error(err);
  } else {
    console.log('No error happened in any steps, operation done!');
  }
});

【讨论】:

    【解决方案2】:

    稍微查看代码并尝试更多地理解它,我相信async.waterfall 是您需要的功能。这将按顺序运行每个函数,将其结果传递给序列中的下一个函数。这是一个例子:

    async.waterfall([
        function(callback)
        {
            // Function 1: do request here...
            callback(null, val); // replace null with a value if you want the waterfall to error and go straight to the end
        },
        function(val, callback) {
            // Function 2: do your second request here
            callback(null, val1, val2, val3); // you can pass any number of variables you like, just make sure the next function in the sequence expects them
        },
        function(val1, val2, val3, callback)
        {
            // Function 3: do your third request here
            callback(null, result);
        } // this can go on for as long as you like
    ], function(err, result)
    {
        // this will be called immediately if the first parameter in any of the callbacks is not null, or when all the functions have run
    });
    

    【讨论】:

      猜你喜欢
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-05
      • 2019-06-24
      相关资源
      最近更新 更多