2015-04-01 46 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