
Ask HN: Is callback hell exaggerated? - tonyle
I played around with just using callbacks as a test and it wasn&#x27;t bad at all.<p>Most information on it seems to start off as a T.V. infomercial for some library.
Don&#x27;t suffer from callback hell, use X!<p>I can barely find anything on the internet about callback hell before 2010 to indicated that it was a real problem at all with javascript.
======
nostrademons
It wasn't really a problem with JS before 2010 because JS wasn't used for
servers. UI programming is usually event-driven, and rarely has long chains of
asynchronous operations (outside of complicated programmer-defined animations,
which few people are using). It became a problem with Node because suddenly
folks are making lots of mutually-dependent network, filesystem, and database
queries, all of which require a callback.

Even then, I think it's a bit overstated - people were writing event-driven
servers in C++ before Javascript was even invented. I do think that being able
to use semicolons to sequence two statements is a lot more concise than
nesting a chain of closures, though.

------
angersock
So, I think an example here will help you understand.

Let's use NodeJS with Express and with pg-node. Let's say you have a database.

    
    
      1. You define an Express handler to handle a get request.
      2. In that handler, you connect to a database, which takes a callback
      3. You create a query on that connection, this takes a callback.
      4. You then write a function that feeds the query result rows into a CSV exporter, which takes a callback (because of course it does).
    

You now have a pyramid something like 5 levels deep. Callback hell is in fact
a thing.

However, I've found that pipeline of promises almost completely solve that
problem.

~~~
tonyle
I'm not sure when promises came to the javascript, but it seems weird that
people would settle with callback hell for so long without even attempting to
refactoring it.

I mean if I didn't have the option of using promises, I would have probably
written something like this.

function handler(callback){

    
    
      var state={};
    
      function logic(step,err,data){  
        if(!step){
          connectToDb("somedatabase",logic.bind(state,1))
        }
        
        if(step==1){
          if(err) callback("error1")
          state.dbInstance=data
          state.dbInstance.query("someQuery",logic.bind(state,2))
        }
        
        if(step==2){
          if(err) callback("error2")
          csvExporter(data,logic.bind(state,3))
        }
    
        if(step==3){
          if(err) callback("error3")
          callback(data)
        }
      }
      logic()
    }

~~~
xyzzy123
Did you mean return callback("error1") etc? Forgetting the return is a classic
bug when you're in callback hell...

~~~
angersock
Yeeeeep.

I think the example and your reply neatly illustrate the problem.

------
MalcolmDiggs
It's a real problem, but so is promise-chain hell, and bound-event hell, and
coroutine hell, and multithread hell, etc etc.

It's not black and white, and no library is going to solve all the issues. A
pragmatic JS engineer is going to have to use many different tools in their
toolbelt on a routine basis, it's just a matter of choosing the right tool for
the job (which includes taking into account the environment you're working in
and the code that already exists).

But in general, in my experience, callback hell is often a sign of an upstream
design-pattern issue. If the procedure you're writing needs to call a series
of 20 functions, in sequence, (and wait for them all to callback one after the
other) you can probably implement it in a clean way that doesn't require your
code to move evermore to the right. Frameworks like Express (which passes
around "next"), and Mocha (which passes around "done") set great precedent of
alternative ways to conceptualize those kind of issues. Achieving this in
practice often means writing a combination of promises, callbacks, and other
things.

------
zzzcpan
Yeah, callback hell is not a real thing. People tend to dislike callbacks only
when they don't have much experience with them. I remember being like that
myself. But there are a lot of problems that are inherently asynchronous and
are much easier to solve with callbacks, than with anything else.

------
smt88
No.

It depends on how much of your business logic must be synchronous and how much
it relies on asynchronous operations. It also depends on what you consider to
be hellish.

async/await is still cleaner than even a single promise, so you might as well
use it.

~~~
nojvek
Agree with this. Async await is just a lot cleaner syntax. The problem with
callback hell is making sense of flow and handling the error at every step.

Promises certainly help but you also see abuse of then callback hell where
rather than chaining, someone would nest the thens.async await is also great
for debugging.

------
antoineMoPa
It is a problem that is easily fixed. I like the fact that javascript allows
you to write ugly code to make something work fast. When it works, you can
refactor quickly by naming anonymous functions / using Promises / using
whatever framework.

Here is my nodejs algorithm so far:

    
    
        - Code something ugly with 4-7 anonymous function levels
        - Realize I'm in callback hell
        - Refactor and make sure all functions have access 
          to the variables they need.
          (Because the scope is often changed while refactoring)
        - Test
        - Repeat

------
kazinator
Callbacks are successfully applied in lower-level languages. When a serial
driver in Linux receives characters, generally at interrupt time, it invokes a
callback in the TTY layer. You don't hear kernel developers whining about
"callback hell". These C callbacks are just function pointers: any closure-
like semantics is simulated by registering a pointer to data along with the
function pointer, which is then passed in the callback call.

------
znpy
No it is not.

------
Kinnard
No.

~~~
antoineMoPa
Could we have more information/reasons?

