2012-09-10 56 views
8

构建我的第一个“严重”的Node.js项目(使用Express)。在Node.js中异步调用API模式

我需要对几个REST API使用几个调用,收集所有结果,按摩它们并返回一个完整的JSON到客户端(HTML5 + AJAX)。

  1. 呼叫API甲
  2. 呼叫API乙
  3. 呼叫API再次A(从乙结果)
  4. 处理结果从3个电话接入JSON
  5. response.send(结果)

我敢肯定/希望有一个简单的模式,或解决方案,或模块,我只是没有正确的谷歌:) 我也希望意见o n在哪里进行这种操作(在'路线'下?分离文件?等等)

感谢您的时间!

+0

这只是一个普通的异步编程问题。我认为它不太适合stackoverflow,因为有许多不同的方式来解决它(纤维,异步库,事件处理)。你应该只使用非常有名的但非常有用的Q库来使用promise。这是一个有见解的答案,所以我将它作为评论留下。我希望现在关闭此问题。 –

+5

@AndyRay这是一件好事,你还不能关闭问题。 – Tomalak

+0

@AndyRay对于提出一般问题没有规定。我正在寻找最好的工具,因为我正在学习如何正确解决问题的方法。如果您有答案,请将其作为一个答案 - 我很乐意详细了解您提供的每种解决方案,并且您可能会获得一些积分。关闭一个问题,因为你已经知道它的答案击败了整个网站的目的:) –

回答

8

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。它将根据他们的要求确定运行功能的最佳顺序。

+0

+1我写了同样的答案(你打败了我)。缺少的一件事就是说明如何从1,2和3中得到所有结果进入步骤4. – Tomalak

+0

看起来像我在找的东西。但有一个问题:我能否将.waterfall与.parallel结合起来?即平行所有呼叫和瀑布相互依赖的呼叫?我有超过3个电话,有一些有趣的依赖... –

+3

@TravelingTechGuy然后你可以使用[async.auto](https://github.com/caolan/async#auto) – qiao

2

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

https://github.com/caolan/async

从您上面所描述的东西,你可能想看看使用并行功能

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

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

编辑:我错过了关于API调用依赖的位。无论何时您需要沿着链传递值并控制您需要使用瀑布方法的顺序(请参阅乔的答案)。如果存在呼叫是独立的情况,您可以使用并行方法。并行方法的一个例子是下面

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

+1

中使用'parallel()'的承诺,因为a)它不会执行定义的序列中的步骤,并且b)无法传递结果从一个功能到另一个功能。 – Tomalak

+0

谢谢,错过了。编辑我的回答 – wdavo

+0

这不仅是关于顺序。这也是关于从一步到另一步的结果。 'parallel()'就是不对的。 – Tomalak