2015-04-01 70 views
1

我最近開始使用NodeJS和MongoDB(使用Monk)。這是當我遇到「回撥地獄」這個詞。在我的代碼中,我正在做同樣的事情。對於一個示例 -回調地獄和嵌套承諾之間的區別

DBCall(d1, function(e, docs){ 
if(docs.length!=0) 
    DBCall(d2, function(e, docs1){ 
    if(docs1.length!=0) 
    DBCall(d3, function(e, docs2){ 
     //doing something with docs,docs1,docs2 
    }) 
    }) 
}) 

這是當我開始閱讀的「承諾」,我碰到這個文章來了 - https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

因爲我需要第三回調之內的兩次文檔和docs1所以我用嵌套的承諾。

DBCall(d1) 
.then(function(docs){ 
    if(docs.length!=0) 
    return DBCall(d2) 
    .then(function(docs1){ 
    if(docs1.length!=0) 
     return DBCall(d3) 
     .then(function(docs2){ 
     //doing something with docs,docs1,docs2 
     }) 
    }) 
    }) 

從上面的代碼片段,我有以下問題(/疑惑):

  1. 除了使代碼更易讀,並承諾具有性能優勢?
  2. 嵌套承諾和回調地獄看起來與我相似。實際上有什麼區別嗎?

我對這個承諾的概念很陌生。任何幫助表示讚賞。

+0

從技術上講,你的嵌套承諾仍然使用回調,從而重新創建「回調地獄」。這次更多的代碼。 – 2015-04-01 13:10:29

+0

那麼如果我使用承諾並且如果我想使用文檔,docs1,docs2,那麼是否有避免回調地獄的方法? – Zee 2015-04-01 13:20:23

+0

@用戶 - 看看我更新的答案中的一些鏈接。 – 2015-04-01 14:18:34

回答

2

基本上,Promise的目的是以讀取同步性的方式允許功能組合和錯誤處理。承諾允許你讀取線性(可能是錯誤的術語)或同步fasion的代碼。

這是一個很寬泛的問題,但請看看這些建議的鏈接。

https://promise-nuggets.github.io/
https://blog.domenic.me/youre-missing-the-point-of-promises/

also this link

編輯: 看完你的更新,什麼你基本上要求是加入的承諾(我認爲)

SO Post給出了一些很好的信息。一些更好的圖書館具有實用功能來幫助實現這一目標。

例如,如果使用藍鳥看一看的join function

+0

您提供的鏈接真的很有幫助。我的情況與「連接函數」類似,只是如果返回的結果(在本例中爲docs/docs1)不是空的,我只想進行下一次調用。 – Zee 2015-04-02 04:43:03

+0

@用戶很酷,很高興它的幫助。如果您需要在回調風格(第一個示例)中運行類似的東西,請嘗試查看[異步模塊](https://github.com/caolan/async)。你可以做基本相同的,但在常規回調fasion。 – 2015-04-02 05:33:39

2

除了使代碼更易讀,並承諾具有性能優勢?

可能不是。

嵌套承諾和回調地獄看起來類似於我。實際上有什麼區別嗎?

承諾不會自動阻止回調地獄。但是因爲它們比「簡單」回調更靈活,所以它們可以用不同的方式組成,這使得迴避地獄更容易。


因爲我需要第三回調之內的兩次文檔和docs1所以我用嵌套的承諾。

有時嵌套的承諾是不可避免的。但是,如果不必按順序執行,則不需要將它們嵌套在一起。你可以並行執行它們:

Promise.all([ 
DBCall(d1), 
DBCall(d2), 
DBCall(d3) 
]).then(function(docs) { 
    // docs is an array: [docs, docs1, docs2] 
}); 
+0

這是一個很好的解決方案。但是我的情況稍微複雜一些。我編輯了這個問題以便更好地理解。 – Zee 2015-04-01 13:33:31