Single Thread vs. Blocking IO:
Graphs of Callbacks vs. Sequential Synchronous Programs:
… we lose the ability to write down a sequential algorithm; instead for non-trivial sequential code, we end up with a graph of callbacks.
Bottleneck of Using Callbacks - Callback Hammer:
This becomes even more critical for large scale applications that make heavy use of asynchronicity. Using callback-passing for asynchronous actions does not compose very well and might create complex flows of passing callbacks around to handle return values.
The CommonJS group has an answer for this in the form of Promises, which aim to provide an interface for interacting with an object that represents the result of an action that is performed asynchronously, and may or may not be finished at any given point in time. This way different components can return promises for asynchronous actions and consumers can utilize the promises in a predictable manner. Promises can also provide the fundamental entity to be leveraged for more syntactically convenient language-level extensions that assist with asynchronicity.