jQuery ajax commandes de rappel différées

Je ne parviens pas à exécuter les rappels effectués / échec / toujours sur chacune de mes demandes ajax avant les rappels de l’object différé.

Le problème que j’ai est que certaines de mes demandes ajax peuvent échouer, mais je dois exécuter le même code, qu’il échoue ou non.

Difficile à expliquer exactement, j’ai donc créé ce violon pour montrer le problème que je rencontrais. http://jsfiddle.net/zZsxV/

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

J’ai lu beaucoup de réponses sur ce sujet mais je ne pense pas que cela corresponde exactement à mes besoins.

Si vous avez besoin de plus d’informations pour l’aider, faites-le-moi savoir et je l’appendai dès mon retour. Merci d’avance.


modifier

Je comprends ce qui se passe. Je sais juste comment le faire pour éviter ce problème. J’ai aussi essayé d’utiliser .then avec les mêmes résultats. Une fois qu’une demande est rejetée, le rappel échoué est déclenché avant d’attendre les autres rappels.

Selon la documentation de jQuery, $.when déclenche des rappels lorsque tous les parameters sont résolus ou que l’ un d’entre eux est rejeté. Alors, pourquoi ne pas utiliser quelque chose comme ça au lieu de $.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); }); }; 

et vous pouvez l’utiliser comme ça:

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

et jsFiddle demo .

Je vois ce que vous essayez de faire ici, mais il n’ya pas de méthode commode. Cela marche:

JSFIDDLE

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

Une autre option serait d’écrire votre propre fonction simple. Voir mise à jour FIDDLE :

 whenAllResolved(a1, a2, a3).done(function () { $('body').append('defer always <-- should be after all
'); }); 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; }

Hey j’ai eu un problème similaire à celui-ci, je n’ai pas le code avec moi mais je vais essayer de le trouver.

Quoi qu’il en soit, ce que j’ai fait était une variable avec le nombre d’objects que j’avais besoin d’attendre, puis diminuez-la lorsque l’un d’eux est terminé, puis vérifiez si la valeur est 0 si c’est possible.