Mohan pd.
Mohan pd. Author of The Coders Blog. Also a professional fullstack javascript developer working with various tech company and client around world.

Asynchronous Programming, Callback Hell and Avoiding Callback Hell

Sep 22, 2019 · 2 minutes
Asynchronous Programming, Callback Hell and Avoiding Callback Hell

Asynchronous Programming is also referred  as Continous Passing Style(CPS) programming. Async functions take an extra argument, which is a function that is called after the async code has finished executing. This extra argument is referred as continuation or callback function.

Important Convention: If a function takes a callback function as an argument, it should be the final argument. Also, if the same function takes an error as an argument, that should be the first argument

Callback is  Function that is executed asynchronously (or at a later time in the event loop). Asynchronous programs execute different functions at different time based function’s speed and order. (Eg: a file read from system will take more time).

An Example of Blocking I/O, Non-Blocking I/O & Callback

Consider that you are visiting a fast food joint where you order a burger at cash counter. The cash counter will take your order and will make you wait for your order to complete. In the mean time, the cash counter can take other orders and start cooking them for other people too.

If you are made to wait at the cash counter for your order, blocking all other customers in line from ordering while the fast food joint completes your order. That’s BLOCKING I/O since completing orders happen one at a time. There will be some amount of idle time while the food is being cooked.

Nodejs in NON-BLOCKING, meaning it can take as many orders and complete them based on the time taken to cook a particular order.

Now, imagine that the fast food joint has given you number on your table while you wait for your meal. That’s a callback (the number).

Callback Hell

It occurrs when callbacks are nested within callbacks. It leads to difficutly in maintaining and confusion. It is also referred as Pyramid of Doom.

Example

fs.exists(fileName, function(exists) {
  if (exists) {
    fs.stat(fileName, function(error, stats) {
      if (error) {
        throw error;
      }
      if (stats.isFile()) {
        fs.readFile(fileName, "utf8", function(error, data) {
          if (error) {
            throw error;
          }
          console.log(data);
        });
      }
    });
  }
});

 

Avoiding Callback Hell

  • One way is to use named functions instead of anonymous functions.

  Example

function cbReadFile(error, data) {
  if (error) {
    throw error;
  }
  console.log(data);
}
function cbStat(error, stats) {
  if (error) {
    throw error;
  }
  if (stats.isFile()) {
    fs.readFile(fileName, "utf8", cbReadFile);
  }
}
function cbExists(exists) {
  if (exists) {
    fs.stat(fileName, cbStat);
  }
}
fs.exists(fileName, cbExists);