Callback Hell!
Here is the structure of our application, which simulates getting transactions for the most recent loan associated with the account number of our user.
// getUser(), getLoans(), and getTransactions() not shown!
console.log("listening for events");
getUser(1, (user) => {
getLoans(user["Account number"], (loans) => {
getTransactions(loans["Most recent"], (transactions) => {
console.log(transactions);
});
});
});
console.log("still listening for events!");
Notice, if the functions getUser
, getLoans
, and getTransactions
were synchronous, the program would look like this:
// getUser(), getLoans(), and getTransactions() not shown!
console.log("listening for events");
const user = getUser(1);
const loans = getLoans(user["Account number"]);
const transactions = getTransactions(loans["Most recent"]);
console.log(transactions);
console.log("still listening for events!");
The second snippet corresponding to synchronous code is arguably more readable and easier to understand.
In the asynchronous version, because of the callbacks, we have a deeply nested structure. In practice, this can get much deeper. This pattern is referred to as the callback hell (some resources call it "Christmas tree problem").
method1(arg1, (arg2) => {
method2(arg2, (arg3) => {
method3(arg3, (arg4) => {
method4(arg4, (arg5) => {
method5(arg5, (arg6) => {
method6(arg6, (arg7) => {
// ...
// CALLBACK HELL
// ...
});
});
});
});
});
});