Adieu for-loops

Posted October 1st, 2012 with No Comments

Using many callbacks without embracing a functional style of coding can lead to mistakes that are very difficult to spot.
Consider this example: we have an array of user object and for each of them we need to fetch the first and last name using Facebook Graph API.

Using a procedural style:

for (idx = 0; idx < users.length; idx++) {
  $.api.FB('/'+users[idx].FacebookId)
    .done(function(fb) {
      users[idx].first_name = fb.first_name;
      users[idx].last_name = fb.last_name;
    });
}

This is just a pseudo code, suppose the method $.api.FB() fetches information from Graph API.
At the end of the cycle, each record has the fields first_name and last_name filled in with values from Facebook.
That in theory.

The problem with this piece of code is that it launches several asynchronous operations and you cannot tell which one is going to end first, likely the entire loop will end even before the first asynchronous operation is complete.
In a cloud environment, where every request could hit a different physical server, is not assured that the first call will end before the next one.

To avoid this error, just turn the code in a functional style:

  $(user).each(function(idx) {
    $.api.FB('/'+users[idx].FacebookId)
      .done(function(fb) {
        users[idx].first_name = fb.first_name;
        users[idx].last_name = fb.last_name;
      });
    }
  });

Here it works because the idx var it’s local to the anonymous function inside the each and, thanks to the closures, it will live until the functions defined inside the scope (the callback) are complete.
Every time we create an anonymous function we have a brand new context in which we can mess around without worrying about what is happening before and after: less side effects and less errors, adieu for loops.

  • Categories

  • Tags

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2 other subscribers

  • Follow me on Twitter