JQuery: $ .when AJAX deferred calls - one failed call cancels the other

I make several API calls, after which I want to load the combined results of each call:

$.when( $.get(localAPI, data, function(response) { globalStore.localShares = Number(response); }), $.get(facebookAPI, '', function(response){ globalStore.facebookShares = Number(response[0].share_count); }), $.getJSON(pinterestAPI, {url: url}).done(function(response){ globalStore.pinterestShares = Number(response.count); }) ).always(function(){ //Do stuff }); 

If the call to $.get fails, the callback function $.always is still executing.

But

If only one call to $.get fails, it cancels the previous calls.

So, if the first call fails, globalStore returns with two elements. If the first call succeeds but the second fails, globalStore returns only one item. And if the first two calls succeed, but the last fails, globalStore returns empty.

Is there any way around this?

Edit:

Yes, I tried to handle the crash in $.when as follows:

 $.when( $.get(mu30_ajax_frontend.ajaxurl, data, function(response) { globalStore.localShares = Number(response); }).fail(function(){ globalStore.localShares = 0; }), $.get(facebookAPI, '', function(response){ globalStore.facebookShares = Number(response[0].share_count); }).fail(function(){ globalStore.facebookShares = 0; }), $.getJSON(pinterestAPI, {url: url}).done(function(response){ globalStore.pinterestShares = Number(response.count); }).fail(function(){ globalStore.pinterestShares = 0; }) ).always(function(){ //Do stuff }); 

But I get the same result.

+5
source share
3 answers

There is no way around this when using $.when in this way, if one request fails, the whole chain fails.

You will have to collapse yourself using pending messages to know when all calls are completed and always successfully resolve, etc.

 var defs = [new $.Deferred(), new $.Deferred(), new $.Deferred()]; $.get(localAPI, data, function(response) { globalStore.localShares = Number(response); defs[0].resolve(true); }).fail(defs[0].resolve); $.get(facebookAPI, '', function(response){ globalStore.facebookShares = Number(response[0].share_count); defs[1].resolve(true); }).fail(defs[1].resolve); $.getJSON(pinterestAPI, {url: url}).done(function(response){ globalStore.pinterestShares = Number(response.count); defs[2].resolve(true); }).fail(defs[2].resolve); $.when.apply($, defs).then(function(result) { // result is an array, any true value is a successful request "[true, true, true]" }); 

written verbose, it can be embellished with some functions and loops, etc.

+5
source

I think the solution I needed was really simple. I didn't care about success or failure, I just wanted to know when ajax was made. So:

 $.get(mu30_ajax_frontend.ajaxurl, data, function(response) { globalStore.localShares = Number(response); }); $.get(facebookAPI, '', function(response){ globalStore.facebookShares = Number(response[0].share_count); }); $.getJSON(pinterestAPI, {url: url}).done(function(response){ globalStore.pinterestShares = Number(response.count); }); $(document).ajaxStop(function(){ //Do stuff }); 
0
source

From jQuery $.when() docs (my highlight):

In the case when several transferred objects are passed to jQuery.when (), the method returns Promise from the new "master" Deferred object, which tracks the state of the aggregate of all transferred deferrals. The method will allow its owner Defer, as soon as all the Deferred decisions are resolved, or reject the Deferred master, as soon as one of the Deferred decisions is rejected .

So, yes jQuery.when will immediately fail if one of the promises passed is rejected / does not work.

0
source

Source: https://habr.com/ru/post/1242731/


All Articles