2012-09-10 55 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