jQuery .when dépannage avec un nombre variable d’arguments

J’ai un problème avec jQuery.when () pour attendre que plusieurs requêtes ajax se terminent avant d’appeler une autre fonction.

Chaque requête ajax obtiendra des données JSON et ressemblera à ceci:

function loadData(arg){ var ajaxCall = $.ajax( URL // depends on arg ) .error( .... ); return ajaxCall; } 

Lorsque la demande est appelée, la valeur de retour (ajaxCall) est ajoutée à une liste appelée ajaxRequests.

  ajaxRequests = []; ajaxREquests.push(loadData(arg)) 

Lorsque toutes les demandes ont été faites, j’essaie de passer ajaxRequests à $ .when pour pouvoir attendre que toutes les demandes soient terminées.

  var defer = $.when.apply($, ajaxRequests); defer.done(function(args){ for (var i=0; i<args.length; i++){ inst.loadData($.parseJSON(args[i].responseText)); } inst.draw(); }); 

inst est un object qui charge et dessine des graphiques basés sur des données JSON.

Le problème est qu’il ne semble pas attendre réellement que les demandes se terminent – args [i] est un object, mais responseText n’est pas défini lorsque le code est exécuté. Si je sauve args [i] et que j’y accède plus tard depuis la console, cela fonctionne.

Je soupçonne que le problème est lié à l’utilisation de .when avec un nombre arbitraire d’arguments, car tous les exemples que j’ai vus sur le Web lui donnent une liste d’arguments prédéfinie.

Je ne sais pas si appliquer a été la bonne idée ou non, mais dans tous les cas, cela ne fonctionne pas correctement et se comporte de manière erratique (en fonction du navigateur).

Toute aide serait grandement appréciée.

S’il vous plaît laissez-moi savoir si plus d’informations sont nécessaires.
J’utilise jQuery 1.5

Bien qu’Alex ait effectivement fourni une solution à son problème, j’ai trouvé la suite un peu difficile. J’avais un problème similaire au sien que j’avais résolu et je souhaitais partager ma solution avec quiconque devait traiter un nombre variable de demandes ajax.

 // Array of requests var requests = Array(); requests.push($.get('responsePage.php?data=foo')); requests.push($.get('responsePage.php?data=bar')); var defer = $.when.apply($, requests); defer.done(function(){ // This is executed only after every ajax request has been completed $.each(arguments, function(index, responseData){ // "responseData" will contain an array of response information for each specific request }); }); 

En plus de la réponse de Andy Corman (je ne suis pas encore en mesure de répondre à un message, je pense …), si vous n’avez qu’une seule demande, les informations de réponse seront transmises directement à la fonction defer.done – en tant qu’argument; Donc, vous devez fournir un si pour ce cas:

 // Array of requests var requests = Array(); requests.push($.get('responsePage.php?data=foo')); var defer = $.when.apply($, requests); defer.done(function(){ // This is executed only after every ajax request has been completed if (requests.length == 1) // "arguments" will be the array of response information for the request else $.each(arguments, function(index, responseData){ // "responseData" will contain an array of response information for each specific request }); }); 

Je pense que je l’ai résolu maintenant – le problème était dans le traitement des arguments retournés. .done recevait trois arguments seulement: le texte de la réponse, le statut et l’object jqXHR. Je m’attendais à ce que l’object jqXHR résultant de chaque requête soit transmis.

Je l’ai résolu en déplaçant le code de rappel de chaque requête vers une fonction distincte (c’est-à-dire que l’appel ajax dans loadData spécifie maintenant une fonction de rappel qui effectue l’appel ‘.loadData (…)’) et que la seule chose à faire par l’appel .done est inst.draw (). Cela semble fonctionner correctement: les rappels individuels sont chacun exécutés avant .done ().

Je ne sais pas si c’est exactement comme cela que cela est supposé fonctionner, mais cela semble être efficace.

Essayez ajaxStart et ajaxStop, qui ont des écouteurs pour les demandes ajax ouvertes.

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/