I agree. Sometimes inline asynchronous callbacks work, just like inline code blocks for if statements or for loops. You just need to train your eye to read them as if they were inline code blocks for an if/then/else block or a for loop.
But sometimes when you get many levels deep in if statements or if a synchronous function starts to reach the hundreds of lines it makes sense to break it up into multiple functions that each have a sensible semantic meaning and which fit on a screen or so. This makes the synchronous code easier to read.
The same goes for asynchronous callback functions. The callback hell that I see most often happens when people have hundreds of lines of inception style anonymous callback functions inside of anonymous callback functions. In this case, just as with the synchronous function that got excessively heavy it makes sense to break things up into multiple functions.
It's all about finding the right balance, and when you do the results are very readable and easy to understand whether you are writing synchronous or asynchronous code.
But sometimes when you get many levels deep in if statements or if a synchronous function starts to reach the hundreds of lines it makes sense to break it up into multiple functions that each have a sensible semantic meaning and which fit on a screen or so. This makes the synchronous code easier to read.
The same goes for asynchronous callback functions. The callback hell that I see most often happens when people have hundreds of lines of inception style anonymous callback functions inside of anonymous callback functions. In this case, just as with the synchronous function that got excessively heavy it makes sense to break things up into multiple functions.
It's all about finding the right balance, and when you do the results are very readable and easy to understand whether you are writing synchronous or asynchronous code.