Question

Is there a way to execute multiple calls in a specific order using jquery.when? first customers, second shifts, third params, etc.

$.when(
    service.doCall('GET', 'customers'),
    service.doCall('GET', 'shifts'),
    service.doCall('GET', 'params'),
    service.doCall('GET','columns')
).then(function(customers, shifts, params, columns) {}

Every call returns a deferred promise which is resolved with the result of the call. The reason I want to execute them in a specific order is because i'm showing a modal to show which call is being executed and which call is done executing. In my service class I notify using a custom event when that call is done. For example when the customers are loaded:

loadingPopup.loadingCustomers.notify();

Then in my popup class I listen for these events, as shown below. But since the calls are executed in a random order my events are fired in the wrong order.

me.loadingCustomers.attach(function() {
    me.loadCustomersBusy(false);
    me.loadCustomersDone(true);
    me.loadShiftsBusy(true);
});

me.loadingShifts.attach(function() {
    me.loadShiftsBusy(false);
    me.loadShiftsDone(true);
    me.loadParamsBusy(true);
});

me.loadParams.attach(function() {
    me.loadParamsBusy(false);
    me.loadParamsDone(true);
    me.loadColumnsBusy(true);
});
Was it helpful?

Solution

The solution is not to use $.when to start the chain of calls:

service.doCall('GET', 'customers').then(function() {
    return service.doCall('GET', 'shifts')
}).then(function() {
    return service.doCall('GET', 'params')
}).then(function() {
    return service.doCall('GET','columns')
}).then(...)

Note that this won't give you the benefit of $.when then automatically being called with all four results, so whilst you shouldn't use $.when to start the calls, you can use it to create an additional promise that when resolved will be passed the results of all previous calls.

var def = [];
def[0] = service.doCall('GET', 'customers');
def[1] = def[0].then(function() { return service.doCall('GET', 'shifts') } );
def[2] = def[1].then(function() { return service.doCall('GET', 'params') } );
def[3] = def[2].then(function() { return service.doCall('GET', 'columns') } );

$.when.apply($, def).then(function(customers, shifts, params, columns) {
    ...
});

In this case I create an array of deferred objects, but each successive AJAX call isn't started until the previous one has finished. It then uses $.when.apply($, def) to pass all four deferred object results to the final callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top