Callback hell in nodejs?

Yes you are in callback hell. The solution assuming you don’t want to use async (which I doubt you can justify other than prejudice) consists of:

1) Make more top-level functions. Each function should perform either 1 or 2 IO operations as a rule of thumb.

2) Call those functions, making your code follow a pattern of a long list of short core functions organized into business logic by a small list of control flow “glue” functions.

Instead of:

saveDb1 //lots of code
  saveDb2 //lots of code
    sendEmail //lots of code

Aim for:

function saveDb1(arg1, arg2, callback) {//top-level code}
function saveDb2(arg1, arg2, callback) {//top-level code}
function sendEmail(arg1, arg2, callback) {//top-level code}
function businessLogic(){//uses the above to get the work done}

3) Use more function arguments instead of relying so much on closures

4) Emit events and DECOUPLE YOUR CODE! See how you have nested code writing stuff to the database and then building an email and adding it to a queue? Don’t you see how those two do not need to exist one on top of the other? Emails lend themselves very well to a core business logic emitting events and an email module listening to those events and queueing the mail.

5) Decouple application-level service connection code from specific transaction business logic. Dealing with connections to network services should be handled more broadly and not embedded with a specific set of business logic.

6) Read other modules for examples

As to should you use an async library, you can and should make up your own mind about that but AFTER you know, and know pretty well, each and every one of these approaches:

  1. callbacks and basic functional javascript techniques
  2. events
  3. promises
  4. Helper libraries (async, step, nimble, etc)

Any serious node.js developer knows how to use and work within ALL of those paradigms. Yes, everyone has their favored approach and maybe some nerd rage about the non-favored approaches, but none of these are difficult and it’s bad to get set in your decision without being able to point to some non-trivial code you wrote from scratch in each paradigm. Also, you should try several helper libraries and understand how they work and why they are going to save you boilerplate. Studying the work of Tim Caswell’s Step or Caolan McMahon’s async is going to be very enlightening. Have you seen the everyauth source code’s use of promises? I don’t like it personally but I surely have to admit that the author has squeezed damn near every last bit of repetition out of that library, and the way he uses promises will turn your brain into a pretzel. These people are wizards with much to teach. Don’t scoff at those libraries just for hipster points or whatever.

Also a good external resource is callbackhell.com.

Leave a Comment