The example given in the article of callback hell isn't even a very good one. Why are we using an asynchronous method to fetch users, another asynchronous method to filter them and yet a third one to get their likes and return those. If that's the ultimate goal then, depending on your backend, you can should be able to make that in a single call.
But let's ignore the poor example in the article. Let's say we need to make 3 calls to 3 asynchronous functions and the result ultimately needs to be returned after all 3 functions are finished executing. Do you just nest them like the article? Absolutely not.
Essentially my point is: you can always architect around callback hell and make it better. I've already gotten into projects where I would now consider them "promise hell" where every method returns a promise of a promise of a promise of a promise of a promise and it's just maddening to debug.
Alternatives to callback hell are always context specific. There is no one-shot-cure-all, in my opinion (not even promises or async / await) but there are plenty of steps you can take.
- Can I separate or combine at least two of these asynchronous functions?
- Can I use a pseudo parallel or serial processing pattern ala async.js?
- Can I use a messaging pattern where each message is handled separately with a single callback ala msngr.js or postal.js?
- Can I simply create a response building pattern where many asynchronous methods write to the same response object and, when it's complete, return it?
- Does it make sense to use a promise here? What about the async / await pattern?