762 votes

Attendez jusqu'à ce que tous jQuery Ajax demande?

Comment puis-je faire une fonction d'attendre jusqu'à ce que tous Ajax de jQuery demandes sont fait à l'intérieur d'une autre fonction?

En bref, j'ai besoin d'attendre que toutes les requêtes Ajax pour être fait avant, j'ai exécuter la prochaine. Mais comment?

1027voto

Alex Points 3933

En fait, jQuery définit maintenant un "quand" la fonction de ce but.

http://api.jquery.com/jQuery.when/

Il accepte n'importe quel nombre de droits Différés à des objets comme arguments, et l'exécution d'une fonction lorsque tous d'entre eux à résoudre.

Cela signifie que, si vous voulez lancer (par exemple) quatre requêtes ajax, puis effectuer une action lorsque ils sont en fait, vous pourriez faire quelque chose comme ceci:

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

À mon avis, il en fait une claire et propre syntaxe, et évite impliquant toutes les variables globales telles que ajaxStart et ajaxStop, ce qui pourrait avoir des effets secondaires indésirables de votre page se développe.

Si vous ne savez pas à l'avance combien d'ajax arguments que vous avez besoin d'attendre pour (vous voulez utiliser un nombre variable d'arguments), il peut encore être fait, mais il est un peu plus embêtant. Voir un tableau de Deferreds $.lorsque() (et peut-être de jQuery .lors du dépannage avec un nombre variable d'arguments).

Si vous avez besoin plus profond de contrôle sur les modes de défaillance de l'ajax scripts etc., vous pouvez économiser de l'objet renvoyé par .lorsque() - c'est un jQuery Promesse objet englobant tous les originaux des requêtes ajax. Vous pouvez appeler .alors() ou .fail() pour ajouter des détails à la réussite/l'échec des gestionnaires.

334voto

Si vous voulez attendre jusqu'à ce que toutes les requêtes ajax sont finis dans votre document, n'importe comment beaucoup d'entre eux existe, il suffit d'utiliser $.ajaxStop événement de cette façon:

  $(document).ajaxStop(function () {
      // 0 === $.active
  });

Dans ce cas, il n'est pas besoin de deviner combien de demandes peut être dans l'application qui pourrait finir dans l'avenir. Dans certains cas, une requête ajax peut être dans le cadre d'une fonction logique interne qui peut être tranquille compliqué et en appeler une autre, alors dans ce cas, vous pourriez ne pas attendre jusqu'à ce que la fonction se fait avec c'est toute la logique plutôt que d'attendre simplement que pour l'ajax pour terminer.

$.ajaxStop ici peut également être lié à tout nœud html que vous pensez peut-être modifié par l'ajax.

33voto

jamietelin Points 3244

J'ai trouvé une bonne réponse par gnarf mon auto qui est exactement ce que je cherchais :)

jQuery ajaxQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

Ensuite, vous pouvez ajouter une requête ajax à la file d'attente comme ceci:

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });

22voto

BBonifield Points 3106

Vous pourriez probablement vous en tirer avec un simple comptage de sémaphore, bien que comment la mettre en œuvre, serait dépend de votre code. Un exemple simple serait quelque chose comme...

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

Si vous voulais que cela fonctionne comme {async: false}, mais vous ne voulez verrouiller le navigateur, vous pourriez faire la même chose avec un jQuery file d'attente.

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});

10voto

shmuel613 Points 838

jQuery permet de spécifier si vous souhaitez que la requête ajax asynchrone ou pas. Vous pouvez tout simplement faire des requêtes ajax synchrone et puis le reste du code ne sera pas exécuté jusqu'à leur retour.

Par exemple:

jQuery.ajax({ async: false,....});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X