JQuery ajax pending callback orders

I cannot get processed / failed / always callbacks for each of my ajax requests to execute before the deferred object callbacks.

The problem is that some of my ajax requests may fail, but I need to execute the same code if one of them fails or no one works.

It’s hard to explain for sure, so I made this script to help show the problem I am having. http://jsfiddle.net/zZsxV/

var a1 = $.Deferred(); var a2 = $.Deferred(); var a3 = $.Deferred(); a1.done(function() { $('body').append('a1 done<br />'); }).fail(function() { $('body').append('a1 fail<br />'); }).always(function() { $('body').append('a1 always<br />'); }); a2.done(function() { $('body').append('a2 done<br />'); }).fail(function() { $('body').append('a2 fail<br />'); }).always(function() { $('body').append('a2 always<br />'); }); a3.done(function() { $('body').append('a3 done<br />'); }).fail(function() { $('body').append('a3 fail<br />'); }).always(function() { $('body').append('a3 always<br />'); }); var def = $.when(a1, a2, a3); def.always(function() { $('body').append('defer always <-- should be after all<br />'); }); setTimeout(function() { a1.resolve(); }, 5000); setTimeout(function() { a2.reject(); }, 1000); setTimeout(function() { a3.resolve(); }, 3000); 

I read a lot of answers on this topic, but I do not believe that this exactly matches my need.

Any information needed to help, let me know and I will add it when I get back. Thanks in advance.


Edit

I understand what is happening. I just know how to do this to avoid this problem. I tried to use. The same thing with the same results. When one request is denied, it calls an error callback before waiting for other callbacks.

+6
source share
3 answers

According to the jQuery $.when documentation, a $.when triggered when either all parameters are allowed, or one of them is rejected. So, how about using something like this instead of $.when :

 var custom_when = function() { var args = $.makeArray(arguments); var callback = args.pop(); var all = []; $.each(args, function(index, def) { def.always(function() { var idx = all.indexOf(def); if (idx !== -1) { all.splice(idx, 1); } if (!all.length) { callback(); } }); all.push(def); }); }; 

and you can use it like this:

 custom_when(a1, a2, a3, function() { // do some stuff. }); 

and jsFiddle demo .

+2
source

I see what you are trying to do here, but there is no convenient method. It works:

JSFIDDLE

 $.when(a1).done(a2).done(a3).then(function() { $('body').append('defer always <-- should be after all<br />'); }); 

Another option is to write your own simple function. See Updated FIDDLE :

 whenAllResolved(a1, a2, a3).done(function () { $('body').append('defer always <-- should be after all<br />'); }); function whenAllResolved(){ var d = $.Deferred(), args = arguments, verifyDeferreds = function(){ var allResolved = true; $.each(args, function(i, arg){ if(arg.state() === 'pending'){ allResolved = false; return false; } }); if (allResolved){ d.resolve(); } }; $.each(arguments, function(i, arg){ arg.always(verifyDeferreds); }); verifyDeferreds(); return d; } 
+1
source

Hi, I had a similar problem, I have no code with me, but I will try to find it.

In any case, what I did was a variable with the number of objects that I needed to wait for, and just reduce it when one of them finished, and then check if it was 0 if I could call another function.

0
source

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


All Articles