2015-11-06 47 views
0

目前我正在使用Node和Express構建一個Web應用程序。該應用程序需要訪問另一個API並將該數據推送給用戶。我使用請求庫編寫了API封裝器。示例API函數如下所示:如何在Node.js中使用基於回調的API封裝函數的承諾?

Robinhood.prototype.getAccount = function(callback) { 
    var options = { 
    url: endpoints.accounts, 
    headers: this.headers, 
    method: 'GET', 
    strictSSL: true, 
    json: true 
    }; 
    request(options, callback); 
}; 

通常有必要將此數據推送到視圖。我通過使用快速路線來做到這一點;但是,通常需要進行多個函數調用來檢索我需要的所有信息。這就造成我們熟悉的回調地獄的情況:

app.get('/main', isLoggedIn, function(req, res) { 
     var object = { 
      user : req.user 
     }; 

     var accountData = new Robinhood(req.user.local.rhtoken).getAccount(function(err, httpResponse, body) { 
      if (err) throw err; 
      object.account = body; 
      var portfolioData = new Robinhood(req.user.local.rhtoken).getInvestmentProfile(function(err, httpResponse, body) { 
       if (err) throw err; 
       object.portfolio = body; 
       var userData = new Robinhood(req.user.local.rhtoken).getUser(function(err, httpResponse, body) { 
        if (err) throw err; 
        object.userData = body; 

        console.log(object); 
        res.render('main_pages/maindashboard.ejs', object); 
       }); 
      }); 
     }); 
    }); 

這不僅是可怕的閱讀,但它也使代碼更難以擴展,如果我要到另一塊的數據傳遞給視圖。經過一番研究,我已經看到解決這個問題的最好方法是承諾和發電機。我知道適當的解決方案可能是使用生成器,但我認爲在我嘗試實現一個承諾之前我需要對承諾有更深入的瞭解。我研究了使用Node的Q promise庫,但是,我發現Q.fcall只在函數返回一個值時才起作用,在這種情況下,它不會。 Q庫文檔提到了兩個概念,Deferreds和Q.Promises,我認爲這可能會有所幫助,但我不明白如何實現這些事情。所以我的問題是,如何重寫API函數以返回承諾,或者如何重寫代碼以調用函數並使用承諾檢索數據?

+0

無論如何您都不能使用沒有承諾的生成器,因此您需要首先了解並使用承諾。 – Bergi

+0

您正在尋找['Q.nfcall'和'Q.ninvoke'等](https://github.com/kriskowal/q/wiki/API-Reference#interfacing-with-nodejs-callbacks),而不是' fcall'。 – Bergi

回答

0

一般的概念是你「promisify」你想使用的異步接口。這將創建一個使用現有回調接口的新接口,但只允許您與基於承諾的接口進行交互。

你可以看到如何在這些引用promisify接口幾個例子:

Node.js: serial operations with branching

Make an Api call with javascript promises in recursion

此外,承諾庫,例如Bluebird包含功能自動創建一個承諾接口。

+0

謝謝,在此之後,我目前正在設計我的API,以便能夠被承諾和回調使用。 –

+0

@ChandlerFreeman - 如果我這樣做,我會設計接口以在內部承諾工作,因爲它提供了卓越的功能爲了管理異步操作,然後爲了回調接口,您可以在頂層放置一個回調包裝,以提供額外的基於回調的API。 – jfriend00