Tuesday, October 4, 2016

Saved from Callback Hell

Callback hell is real. Often developers see callbacks as pure evil, even to the point of avoiding them. JavaScriptʼs flexibility does not help at all with this. From the surface, it seems callbacks are the perfect foot gun, so it is best to replace them.

The good news is there are simple steps to get saved from callback hell. I feel eliminating callbacks in your code is like amputating a good leg. A callback function is one of the pillars of JavaScript and one of its good parts. When you replace callbacks, you are often just swapping problems.

A friend tells me callbacks are ugly warts and the reason to study better languages. Well, are callbacks that ugly?

Wielding callbacks in JavaScript has its own set of rewards. There is no reason to avoid JavaScript because callbacks can turn into ugly warts.

Letʼs dive into what sound programming has to offer with callbacks. My preference is to stick to SOLID principles and see where this takes us.

What Is Callback Hell?

I know what you may be thinking, what the hell is a callback and why should I care? In JavaScript, a callback is a function that acts as a delegate. The delegate executes at an arbitrary moment in the future. In JavaScript, the delegation happens when the receiving function calls the callback. The receiving function may do so at any arbitrary point in its execution.

In short, a callback is a function passed in as an argument to another function. There is no immediate execution since the receiving function decides when to call it. The following code sample illustrates:

function receiver(fn) {
  return fn();
}

function callback() {
  return 'foobar';
}

var callbackResponse = receiver(callback); 
// callbackResponse == 'foobar'

If you have ever written an Ajax request, then you have encountered callback functions. Asynchronous code uses this approach since there is no guarantee when the callback will execute.

The problem with callbacks stems from having async code that depends on another callback. I will illustrate the use of setTimeout to simulate async calls with callback functions.

Feel free to follow along, the repo is out on GitHub. Most code snippets will come from there so you can play along.

Behold, the pyramid of doom!

setTimeout(function (name) {
  var catList = name + ',';

  setTimeout(function (name) {
    catList += name + ',';

    setTimeout(function (name) {
      catList += name + ',';

      setTimeout(function (name) {
        catList += name + ',';

        setTimeout(function (name) {
          catList += name;

          console.log(catList);
        }, 1, 'Lion');
      }, 1, 'Snow Leopard');
    }, 1, 'Lynx');
  }, 1, 'Jaguar');
}, 1, 'Panther');

Looking at the above, setTimeout gets a callback function that executes after one millisecond. The last parameter just feeds the callback with data. This is like an Ajax call except the return name parameter would come from the server.

There is a good overview of the setTimeout function on MDN.

I am gathering a list of ferocious cats through asynchronous code. Each callback gives me a single cat name and I append that to the list. What I am attempting to achieve sounds reasonable. But, given the flexibility of JavaScript functions, this is a nightmare.

Continue reading %Saved from Callback Hell%


by Camilo Reyes via SitePoint

No comments:

Post a Comment