0

So a XHR is run inside a loop and I would like to execute a function after all the XHR complete, I tried this with promises as follows.

var promises = [];
for(var i=0;i<5;i++){
    promise = $.ajax({
                    type: "POST",
                    url : data_url,
                    data:pdata
    });
    promises.push(promise);
}
$.when(promises).then(function(){
                window.location.href = '/cart?edit_order=true'
})

The problem is the redirect happens before the AJAX is completed, what am I missing?

HackToHell
  • 2,223
  • 5
  • 29
  • 44
  • I saw that you specified jQuery in the title, but just for history purposes, you can do this in a "better" way and by better i mean better readability and extensibility. `q.all([loadSomething(), loadAnotherThing()]) .spread(function(something, another) { DoSomethingOnThem(something, another); });` Where `loadSomething(), loadAnotherThing()` are two promises and `q.all` is from the following promise library : https://github.com/kriskowal/q – Razvan Dumitru Oct 12 '16 at 11:04

1 Answers1

2

If I remember correctly, jQuery's .when() method didn't accept an Array of promises as argument, but single arguments instead. That just means you need to change the way of invoking it to:

$.when.apply( null, promises ).then(function(){
            window.location.href = '/cart?edit_order=true'
})

Using Function.prototype.apply will automatically take an Array and put each value of that Array as single arguments into the invoked function, in this case, .when(). Effectively spreading the arguments.

You can also do some EMCAscript magic and create a little partial application for that:

var when = Function.prototype.apply.bind( $.when, null );

..and then just call

when( promises ).then(function() { ...
jAndy
  • 231,737
  • 57
  • 305
  • 359
  • You mean apply, which spreads the arguments? – Ruan Mendes Oct 12 '16 at 11:01
  • 1
    You can also use `$.when(..promises)` in recent versions of ES – Ruan Mendes Oct 12 '16 at 12:00
  • Sure, but you "can" also use native promises and arrow functions and everything, but then you should strongly advice the usage of a pre- or transpiler. Destructering is not widely supported in browser versions for now. – jAndy Oct 12 '16 at 12:22
  • Yeah, transpiling can be complicated... but the point is that it's a very elegant way. "In recent versions" was intended as the advice you just stated. – Ruan Mendes Oct 12 '16 at 14:23