Last Updated: August 24, 2017
·
15.15K
· nashio

Avoiding nested asynchronous calls in JS

Rather than having two nested (asynchronous) calls in order make sure the one loads to execute the other, you can use deffereds. Check out jQuery.when( deferreds ). Query the calls with $.when, and use a chained ".then" which happens when this calls get resolved or rejected. Seems a lot human readable to me.

// Nested calls    

 function doSomething(){
   $.getJSON('/api/users', function(data) {
     var Users = data.users;
     $.getJSON('/api/skills', function(data) {
           // doSomethingElse( Users, data.skills ); // do callback
     });
   });
 }

// Cleaner 

function doSomething(){
    $.when( $.getJSON('/api/users'), $.getJSON('api/skills') ).then(function( users, skills ){
        // doSomethingElse( users, skills ); // both resolved here
    });
}​​

7 Responses
Add your response

When multiple AJAX calls are used with a jQuery deferred, isn't it correct that they will run in parallel? In this case, your example is not only easier to read, but has a performance boost. The only disadvantage that should be noted is that if there is a data dependency for the second request, based on the result of the first request, then they need to be nested so that they execute in sequence rather than in parallel.

over 1 year ago ·

@jm9000 Hm, really, I was actually under the impression that this abstraction was a bit slower but prettier.

over 1 year ago ·

@nashio I put together a quick benchmark to demonstrate. This test times two AJAX calls in parallel (deferred) and in sequence (nested). They both use the same AJAX callback, which is a simple PHP script that has a 1s delay, then returns a random number.

over 1 year ago ·

@jm9000 Holly, 1 sec?, that seems a lot. I'm gonna do a test myself to confirm this.

over 1 year ago ·

@nashio Of course it is a lot. The delay is to accentuate the performance difference. I would never have any delay at all in a real application.

over 1 year ago ·

This pattern is called deferred and promises.

Not to mention, there is a whole class of different methods to solving the callback hell problem that everyone is talking about.

An alternative library is async.js. However, it doesn't handle asynchronous calls via promises.

Another one is the Q library. This one uses promises just like jQuery. If you mix Q with async, you can get elegant asynchronous calls.

over 1 year ago ·

What if the second getJSON call requires the result Users? i.e. how do you sequence two or more promises when each subsequent promise relies on the prior's result (without nesting?)

over 1 year ago ·