2

I am sending multiple promise to get user details using ajax.

var a= APP.request('user:getID');//Promise request
var b= APP.request('user:getName');//Promise request
var c= APP.request('user:getNumber');//Promise request
var d= APP.request('user:getAge');//Promise request
$.when(a.done(), b.done(), c.done(), d.done()).done(function() {
    console.log("Saving to single view.");//Working fine when ajax url is up.not working if any one url goes down.
}

This will work if all the url's are up. But if any one url is down it will not enter inside when block.

I just modified the code and introduced then, still same problem.

$.when(a.then(), b.then(), c.then(), d.then()).then(function() {
    console.log("Saving to single view.");
}

I am not able to get what's wrong with my code.

Update: i have to execute $when block only after all the promises are being executed.

Madhukar Hebbar
  • 3,113
  • 5
  • 41
  • 69

1 Answers1

1

I have had success with using an array of promises

var finalCheck = [];

then .push()

finalCheck.push( APP.request('user:getID') ) ;  //Promise request
finalCheck.push( APP.request('user:getName'));  //Promise request
finalCheck.push( APP.request('user:getNumber'));//Promise request
finalCheck.push( APP.request('user:getAge'));   //Promise request

you may or may not benefit from moving some logic into a Defferred function. I like this because I have to do that work after recovery/fallback from a failed subrequest, and this makes that method available from multiple places. The important part here is that the Defferred function comes before the $.when.apply().

var AfterAllRequests = $.Deferred().done(function () {
             // real final work here...
             console.log("Saving to single view.");
        });

and wait for success or failure of those promises

$.when.apply($, finalCheck).done(function () {
            AfterAllRequests.resolve();
        }).fail(function () {
            console.log(" Some GET(s) failed, handle fallback content ...");
            // ....
            AfterAllRequests.resolve();
        });

Untested variant - You could try .always() instead of .done() and .fail() but I (um) always have different things to do depending on success or failure of the group of promises. It would look something like:

$.when.apply($, finalCheck).always(function () {
           // well now it is time....and you may not need a deferred anymore
            AfterAllRequests.resolve();
        });
Stan
  • 985
  • 1
  • 7
  • 12
  • i need to execute one function after all promise executed regardless of fail/pass, make sure i need to execute my method **after all promise execution(done/fail)** – Madhukar Hebbar Jul 09 '15 at 15:01
  • That is the point of `AfterAllRequests.resolve()` - you can do it in `done` and/or `fail` logic. I updated the answer to make this a little clearer. – Stan Jul 09 '15 at 15:05
  • let me try it. But adding same code in success and fail makes no sense right? :-) – Madhukar Hebbar Jul 09 '15 at 15:15
  • `$.when(a.then(), b.then(), c.then(), d.then()).then(function() { myFunction(); }, function(result) {myFunction();});` will even work right? but still it is repeating my function – Madhukar Hebbar Jul 09 '15 at 15:17
  • The common code is refactored into the `defferred` function - so the only repeated code is the `AfterAllRequests.resolve()` that fires the `defferred` function. You could try `.always()` - I'll update the answer – Stan Jul 09 '15 at 15:27
  • Notice that `AfterAllRequests` is fulfilled *as soon as the first* of your request fails, not after all of the promises have settled. If you really were looking for that, then you'd just had to replace `done` with `always` in your original code. – Bergi Jul 09 '15 at 20:19