Skip to content Skip to sidebar Skip to footer

Working With 1 Or More Jquery Promises

I'm making either 1 or more REST/ajax calls to validate some user information. The rest calls are working well and the information is coming back. The issue I'm facing isn't with t

Solution 1:

It seems strange to me that the structure of what is returned would change like that.

Yes, jQuery is horribly inconsistent here. When you pass a single argument to $.when, it tries to cast it to a promise, when you pass multiple ones it suddenly tries to wait for all of them and combine their results. Now throw in that jQuery promises can resolve with multiple values (arguments), and add a special case for that.

So there are two solutions I could recommend:

  • Drop $.when completely and just use Promise.all instead of it:

    var promises = [];
    for (var p of recipients) {
        …
        promises.push( $.ajax({…}));
    }
    
    Promise.all(promises)
    .then(function(results) {
         console.log(results);
    })
    
  • Make each promise resolve with only a single value (unlike $.ajax() that resolves with 3) so that they don't get wrapped in an array, and $.when will produce consistent results regardless of number of arguments:

    var promises = [];
    for (var p of recipients) {
        …
        promises.push( $.ajax({…}).then(function(data, textStatus, jqXHR) {
            return data;
        }) );
    }
    
    $.when.apply($, promises)
    .then(function() {
         console.log(arguments);
    })
    

Solution 2:

It appears this functionality is working as currently documented. When you have multiple deferreds passed to $.when it creates a new Promise object that is resolved with the results of each of the results of the passed in deferreds. When you only pass in one, it returns the deferred that you passed in, thus only returning the result instead of an array of results.

I'm not sure if it is any better than your current solution, but you could force it to always have multiple deferreds by having a "fake" deferred that you skip when evaluating the results.

I.E.

functionensureUsers(recipients){
  var promises = [$.Deferred().resolve()];
  for(var key in recipients){
    var payload = {'property':recipients[key]};
    promises.push( $.ajax({...}));
  }
  return $.when.apply($,promises);    
}

You could also potentially make it so the placeholder deferred is resolved with the same structure as what you expect in your real results so it would just appear that the first response is always a success.

Post a Comment for "Working With 1 Or More Jquery Promises"