jQuery deferred array not triggering .done() as expected

68 views Asked by At

I'm having some trouble with jQuery deferreds. Here's my code:

function makeAjaxCalls(purge){
  var deferreds = [];
  // delete the documents
  _.each(purge, function(element, index, list){
    console.log('purging '+element.model+' id='+element.id);
    deferreds.push(
      $.ajax({
        type: 'DELETE',
        url: '/API/admin/purge/'+element.model+'/'+element.id
      })
    );
  });
  console.log('returning array with '+deferreds.length+' deferreds');
  return deferreds;
};

function purgeDeletedDocs(){
  console.log('purging...');
  var purge = [];
  _.each(arrayOfIDs, function(element, index, list){
    purge.push({'model': arrayOfModels.get(element).get('modelName'), 'id': element});
  }); // [{model: 'modelName', id: 'id'}...]
  // when *all* the AJAX calls are resolved run this code
  $.when.apply(this, deferreds).done(function(){
    console.log('done');
  });
  var deferreds = makeAjaxCalls(purge);
};

purgeDeletedDocs()

As you can see I'm using $.when.apply as I'm returning an array of deferreds from the makeAjaxCalls() function.

Here's what I'm getting in the console:

purging...
done
purging User id=5564e0f647f054512a9d64c9
purging Client id=557079a04407058a49fd2f3d
returning array with 2 deferreds

Now that's odd. I'm seeing the done before the AJAX calls have been even made, let alone resolved. I'm passing this into the apply() but using $ etc. makes no difference - and reading the docs for apply() the first parameter just sets the this for the code so that's the expected behaviour.

The server is correctly getting the API calls made so the AJAX calls are being made, it's just that the multiple deferreds seem to resolve and trigger the .done() before they're even made.

Any ideas as to what am I doing wrong?

1

There are 1 answers

1
Bergi On BEST ANSWER
// when *all* the AJAX calls are resolved run this code
$.when.apply(this, deferreds).done(function(){
    console.log('done');
});
var deferreds = makeAjaxCalls(purge);

As you can see I'm using $.when.apply as I'm returning an array of deferreds from the makeAjaxCalls() function.

Well but you're not passing them into the $.when function. Instead, you are passing undefined to $.when, even before making that call to makeAjaxCalls()!

Reorder your statements to

var deferreds = makeAjaxCalls(purge);
$.when.apply(this, deferreds).done(function(){
    console.log('done');
});