1

I recently started working with NodeJS and MongoDB(using Monk). This is when I came across the term "callback hell". In my code I was exactly doing the same thing. For an example-

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
    }) 
  }) 
}) 

This is when I started reading on "promises", and I came across this article - https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Since I needed both docs and docs1 inside the third callback so I used nested promises.

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
      })
    })
  })

From the above code snippet I have the following questions(/doubts) :

  1. Apart from making the code more readable, does promises have performance benefits?
  2. Nesting promises and callback hell looks similar to me. Is there actually any difference?

I am new to this concept of promises. Any help is appreciated.

Zee
  • 8,420
  • 5
  • 36
  • 58
  • Technically, your nested promises are still using callbacks, thus creating "callback hell" all over again. This time with more code. – KJ Price Apr 01 '15 at 13:10
  • So is there no way of avoiding callback hell if i use promises and if i want to use docs,docs1,docs2 ? – Zee Apr 01 '15 at 13:20
  • @User - take a look at some of the links in my updated answer. – Justin Maat Apr 01 '15 at 14:18

2 Answers2

2

Basically the purpose of Promises is to allow for functional composition and error handling, in a way that reads in a synchronous nature. Promises allow you to read code in a linear (maybe wrong term) or synchronous fasion.

This is sort of a broad question but take a look through these suggested links.

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

also this link

Edit: After reading your updates, what you're essentially asking for is to join the promises (I think)

This SO Post gives some good info. Some of the better libraries have utility functions to help with this.

For example, if using bluebird take a look at the join function

Community
  • 1
  • 1
Justin Maat
  • 1,965
  • 3
  • 23
  • 33
  • The links you provided are really helpful. My situation is similar to the "join function" except that I only want to make the next call if the returned result(in my case docs/docs1) is not empty. – Zee Apr 02 '15 at 04:43
  • @User cool, glad it's helping. If you need to run something similar in a callback style (your first example), try taking a look at the [async module](https://github.com/caolan/async) . You can do basically the same but in the regular callback fasion. – Justin Maat Apr 02 '15 at 05:33
2

Apart from making the code more readable, does promises have performance benefits?

Probably not.

Nesting promises and callback hell looks similar to me. Is there actually any difference?

Promises don't automatically prevent callback hell. But because they are more flexible than "simple" callbacks, they can be composed in different ways, which makes it easier to avoid callback hell.


Since I needed both docs and docs1 inside the third callback so I used nested promises.

Sometimes nested promises are unavoidable. However, there is no need to nest them if they don't have to be executed sequentially. You could execute them in parallel:

Promise.all([
 DBCall(d1),
 DBCall(d2),
 DBCall(d3)
]).then(function(docs) {
  // docs is an array: [docs, docs1, docs2]
});
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • This is a great solution. But my situation is little more complex. I edited the question for better understanding. – Zee Apr 01 '15 at 13:33