Node.js 中对 API 的异步调用模式

Posted

技术标签:

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

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

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

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

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

感谢您的宝贵时间!

【问题讨论】:

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

以上是关于Node.js 中对 API 的异步调用模式的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 事件循环

node事件循环

Node.js 事件循环

Node.js 事件循环

nodejs 事件循环

Node.js 事件循环