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 的异步调用模式的主要内容,如果未能解决你的问题,请参考以下文章