【问题标题】:Express | Making multiple http requests asynchronously快递 |异步发出多个http请求
【发布时间】:2014-04-15 04:50:30
【问题描述】:

我目前正在构建一个小型节点应用程序,它会进行一些 api 调用并呈现一个带有图表的网页。我使用 express 和 jam 作为渲染引擎。

问题是我对 javascript 很陌生,我不知道如何规划我的 http 请求,因此当有多个变量时,我可以传递从 api (http get) 获得的变量对象要求。我不知道如何将其映射出来以制作单个对象并将其发送到玉渲染引擎。

这是我目前所拥有的:

app.get('/test', function(req, res) {
    apiRequestGoesHere(name, function(error, profile) {
        //Get some data here
    });
    anotherApiRequest(tvshow, function(error, list) {
        //Get some data here
    });
    res.render('test', data);
});

就目前而言,页面呈现并且请求尚未完成,如果我将 res.render 放在其中一个请求中,我将无法访问另一个请求的数据。

所以我想要的是一种设置方法,这样我就可以进行多个 api 调用,然后从其余 api 返回给我的一些元素中创建一个对象,并将其发送给 Jade,这样我就可以使用页面上的数据。

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    您可能想使用async 来帮助解决这个问题。 async.parallel 是这样简单的一个不错的选择:

    app.get('/test', function(req, res) {
        async.parallel([
        function(next) {
            apiRequestGoesHere(name, function(error, profile) {
                //Get some data here
                next(null, firstData);
            });
        },
        function(next) {
            anotherApiRequest(tvshow, function(error, list) {
                //Get some data here
                next(null, secondData);
            });
        }], function(err, results) {
            // results is [firstData, secondData]
            res.render('test', ...);
        });
    });
    

    如果相关函数next 的第一个参数应该是一个错误(我输入null) - 一旦调用一个错误,最终函数将调用相同的错误,其余的回调将被忽略。

    【讨论】:

    • 好的,谢谢,这就是我要找的。虽然,有没有办法让我在第二个实例中使用 firstData,我的意思是下一个函数?如果我想在我的第二个 api 调用中传递第一个调用的参数,那将很有用。
    • @user2663041 是的!查看async.waterfall
    • 好的,我正在使用瀑布,但如果您不介意提供帮助,我仍然遇到问题。我有 5 个人的循环,我需要为所有 5 人做一个 http 请求。有没有办法让它等待所有 5 个请求都完成,直到我执行回调,因为它不能在循环中的单个请求的末尾?
    • @user2663041 是的!查看async.each
    【解决方案2】:

    你可以async parallel

    async.parallel([
        function(callback){
            // Make http requests
            // Invoke callback(err, result) after http request success or failure
        },
        function(callback){
            // Make http requests
            // Invoke callback(err, result) after http request success or failure
        }
    ],
    // optional callback
    function(err, results){
        // the results array will be array of result from the callback
    });
    

    【讨论】:

      【解决方案3】:

      您的页面呈现的原因是回调尚未“回调”。为了做你想做的事,你需要做一些类似的事情:

      app.get('/test', function(req, res) {
          apiRequestGoesHere(name, function(error, profile) {
              //Get some data here
              anotherApiRequest(tvshow, function(error, list) {
                  //Get some data here
                  res.render('test', data);
              });
          });
      });
      

      这种策略会导致所谓的“金字塔代码”,因为您的嵌套回调函数最终会越来越深。

      我还推荐 Tim Caswell 的 step 库。它会让你的代码看起来像:

      var step = require('step');
      
      app.get('/test', function(req, res) {
          step(
              function () {
                  apiRequestGoesHere(name, this)
              },
              function (error, profile) {
                  if error throw error;
                  anotherApiRequest(tvshow, this)
              },
              function done(error, list) {
                  if error throw error;
                  res.render('test', list)
              }
          )
      });
      

      您还可以使用group 方法并行进行调用,并且仍然保持回调的顺序。

      Gl, 亚伦

      【讨论】:

      • 具有我从调用中获得的值的对象如何传递以及如何/在何处向对象添加值?
      • 每个函数中的this关键字将调用序列中的下一个函数的回调,数据通过参数传递给下一个函数。请注意,第一个参数通常是一个错误(如果存在)。
      猜你喜欢
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 2018-04-10
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多