【问题标题】:Async calls pattern to API in Node.jsNode.js 中对 API 的异步调用模式
【发布时间】:2012-09-02 23:03:44
【问题描述】:

构建我的第一个“严肃”Node.js 项目(使用 Express)。

我需要对多个 REST API 进行多次调用,收集所有结果,处理它们并将完整的 JSON 返回给客户端(HTML5 + AJAX)。

  1. 调用 API A
  2. 调用 API B
  3. 再次调用 API A(来自 B 的结果)
  4. 将 3 次调用的结果处理成 JSON
  5. response.send(result)

我确定/希望有一个简单的模式、解决方案或模块,我只是没有正确搜索 :) 我也希望对在哪里放置此类操作(在“路线”下?单独的文件?等)提出意见

感谢您的宝贵时间!

【问题讨论】:

  • 这只是一个一般的异步编程问题。我认为它不太适合 stackoverflow,因为有很多很多不同的方法来解决它(纤程、异步库、事件处理)。您应该只使用带有名字非常有用但非常有用的 Q 库的 Promise。这是一个自以为是的答案,所以我将其作为评论留下。我希望现在就结束这个问题。
  • @AndyRay 还好你还不能结束问题。
  • @AndyRay 没有禁止提出一般性问题的规定。我正在寻找最好的工具,因为我正在学习如何正确节点。如果您确实有答案,请将其保留 - 我很高兴了解您提供的每个解决方案的更多信息,并且您可能会得到一些分数。关闭一个问题,因为你已经知道它的答案超过了整个网站的目的:)
  • 我认为这更适合 nodejs 邮件列表 groups.google.com/forum/?fromgroups#!forum/nodejs 它似乎太开放了,无法使用 SO
  • @Andy 一个“开放式”问题需要积累至少几个答案,对吧?到目前为止我还没有看到。此外,这个问题不是关于“最好的方法”,而是“a 方法”。我看不出这怎么不适合 SO 的格式;我真的不明白你的意思。此外,用 “我希望现在关闭” 的评论不仅不是很好。试图影响人们关闭一个问题,因为你不喜欢它也不是基于社区的关闭应该如何工作。

标签: node.js asynchronous express


【解决方案1】:

async 模块适合这种工作。具体来说,你可以使用async.waterfall函数。

例子:

async.waterfall([
    function(callback){
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback){
        callback(null, 'three');
    },
    function(arg1, callback){
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
   // result now equals 'done'    
});

编辑,如果你在工作之间有一些重要的依赖关系,那么你可以使用async.auto。它将根据功能的要求确定运行功能的最佳顺序。

【讨论】:

  • +1 我写的是同样的答案(你打败了我)。缺少的一件事是指示如何将 1、2 和 3 的所有结果放入第 4 步。
  • 看起来像我要找的东西。但是有一个问题:我可以将 .waterfall 与 .parallel 结合起来吗? IE。并行所有调用和瀑布那些相互依赖的?我有超过 3 个电话,有一些有趣的依赖关系......
  • @TravelingTechGuy 那么你可以使用async.auto
  • 谢谢,这个帖子帮了我很多,因为我一直在寻找除了 Node 中的 Promise 之外的链式解决方案
【解决方案2】:

周围有很多控制流库。我在以前的项目中使用过 Q,对此我没有任何抱怨,但是我可能会考虑在我的下一个项目中使用 caolan 的异步库。

https://github.com/caolan/async

根据您上面的描述,您可能想看看使用并行函数

https://github.com/caolan/async#parallel

您描述的问题可以很容易地转移到文档中的并行示例

编辑:我错过了关于 API 调用依赖的一点。每当您需要沿链传递值并控制您需要使用瀑布方法的顺序时(请参阅 qiao 的答案)。如果存在调用独立的情况,您将使用并行方法。下面是并行方法的一个例子

async.parallel({
    google: function(callback){
      http.get("http://www.google.com", function(res){
        console.log("google done");
        callback(null, res.statusCode);
      })
    },
    yahoo: function(callback){
      http.get("http://www.yahoo.com", function(res){
        console.log("yahoo done");
        callback(null, res.statusCode);
      })    
    }
  },
  function(err, results) {
    if(!err){
      console.log("all done");
      console.log(results.google);
      console.log(results.yahoo);
    }else{
      console.log(err);
    }
  }
);

这样做的目的是并行处理您的所有请求,并在所有请求完成后给您一个回调。这是您可以处理数据的地方。

控制流库列表:

https://github.com/joyent/node/wiki/Modules#wiki-async-flow

【讨论】:

  • parallel() 不起作用,因为 a) 它不会按定义的顺序执行步骤,b) 无法将结果从一个函数传递到下一个函数。跨度>
  • 谢谢,错过了。编辑了我的答案
  • 这不仅仅是关于订单。这也是关于将结果从一个步骤传递到另一个步骤。 parallel() 不适合那样做。
猜你喜欢
  • 2019-07-14
  • 2013-02-16
  • 2017-03-10
  • 2016-03-30
  • 1970-01-01
  • 2014-05-13
  • 2012-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多