web-dev-qa-db-fra.com

jquery comment utiliser plusieurs appels ajax l'un après l'autre

Je suis dans l'application mobile et j'utilise plusieurs appels Ajax pour recevoir des données d'un serveur Web, comme ci-dessous.

function get_json() {
    $(document).ready(function() {
        $.ajax({
            url: 'http://www.xxxxxxxxxxxxx',
            data: {
                name: 'xxxxxx'
            },
            dataType: 'jsonp',
            //jsonp: 'callback',
            //jsonpCallback: 'jsonpCallback',
            success: function(data) {
                $.each(data.posts, function(i, post) {
                    $.mobile.notesdb.transaction(function(t) {
                        t.executeSql('INSERT into bill (barcode, buildingcode, buildingaddress, flatname, flatdescription, entryseason, period, amount, pastpayments, todaypayments, paydate, receiptno) VALUES (?,?,?,?,?,?,?,?,?,?,?,?);', [post.Id, post.Code, post.Address, post.Name, post.Description, post.EntrySeason, post.Period, post.Revenue, post.PastPayments, post.todaypayments, post.paydate, post.receiptno],
                        //$.mobile.changePage('#page3', 'slide', false, true),  
                        null);
                    });
                    $('#mycontent').append(post.Name);
                });
            }
        });

        $.ajax({
            xxxx
        });

        $.ajax({
            xxxx
        });
    });
}

Comment puis-je forcer le 2ème appel ajax à commencer après la fin du premier ... le 3ème après la fin du 2ème et ainsi de suite?

34
kosbou

Placez-les à l'intérieur du success: de celui sur lequel il s'appuie.

$.ajax({
    url: 'http://www.xxxxxxxxxxxxx',
    data: {name: 'xxxxxx'},
    dataType: 'jsonp',
    success: function(data){

        // do stuff

        // call next ajax function
        $.ajax({ xxx });
    }
});
43
Timothy Aaron

Vous êtes un peu proche, mais vous devriez placer votre fonction dans le gestionnaire d'événements document.ready au lieu de l'inverse.

Une autre façon de procéder consiste à placer votre appel AJAX dans une fonction générique et à appeler cette fonction à partir d'un rappel AJAX pour effectuer une boucle dans un ensemble de demandes dans l'ordre:

$(function () {

    //setup an array of AJAX options,
    //each object will specify information for a single AJAX request
    var ajaxes  = [
            {
                url      : '<url>',
                data     : {...},
                callback : function (data) { /*do work on data*/ }
            },
            {
                url      : '<url2>',
                data     : {...},
                callback : function (data) { /*maybe something different (maybe not)*/ }
            }
        ],
        current = 0;

    //declare your function to run AJAX requests
    function do_ajax() {

        //check to make sure there are more requests to make
        if (current < ajaxes.length) {

            //make the AJAX request with the given info from the array of objects
            $.ajax({
                url      : ajaxes[current].url,
                data     : ajaxes[current].data,
                success  : function (serverResponse) {

                    //once a successful response has been received,
                    //no HTTP error or timeout reached,
                    //run the callback for this request
                    ajaxes[current].callback(serverResponse);

                },
                complete : function () {

                    //increment the `current` counter
                    //and recursively call our do_ajax() function again.
                    current++;
                    do_ajax();

                    //note that the "success" callback will fire
                    //before the "complete" callback

                }
            });
        }
    }

    //run the AJAX function for the first time once `document.ready` fires
    do_ajax();

});

Dans cet exemple, l'appel récursif pour exécuter la demande AJAX suivante est défini en tant que rappel complete afin qu'il s'exécute quel que soit le statut de la réponse en cours. Ce qui signifie que si la requête expire ou renvoie une erreur HTTP (ou une réponse invalide), la requête suivante sera toujours exécutée. Si vous souhaitez que les demandes suivantes ne soient exécutées que lorsqu'une demande aboutit, il est préférable d'utiliser le rappel success pour passer votre appel récursif.

Mise à jour 2018-08-21 en ce qui concerne les bons points dans les commentaires.

46
Jasper

Emballez chaque appel ajax dans une fonction nommée et ajoutez-les simplement aux rappels de succès de l'appel précédent:

function callA() {
    $.ajax({
    ...
    success: function() {
      //do stuff
      callB();
    }
    });
}

function callB() {
    $.ajax({
    ...
    success: function() {
        //do stuff
        callC();
    }
    });
}

function callC() {
    $.ajax({
    ...
    });
}


callA();
9
Skylar Anderson

Ceci est la solution la plus élégante que je utilise depuis un moment. Il ne nécessite pas de variable de compteur externe et fournit un bon degré d'encapsulation.

var urls = ['http://..', 'http://..', ..];

function ajaxRequest (urls) {
    if (urls.length > 0) {
        $.ajax({
            method: 'GET',
            url: urls.pop()
        })
        .done(function (result)) {
            ajaxRequest(urls);
        });
    }
}

ajaxRequest(urls); 
7
zoxxx

Vous pouvez également utiliser jquery when, puis des fonctions. par exemple 

 $.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {
  //another ajax call
});

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

7
Lyon

Je considère que ce qui suit est plus pragmatique puisqu'il ne séquence pas les appels ajax mais c'est sûrement une question de goût.

function check_ajax_call_count()
{
    if ( window.ajax_call_count==window.ajax_calls_completed )
    {
        // do whatever needs to be done after the last ajax call finished
    }
}
window.ajax_call_count = 0;
window.ajax_calls_completed = 10;
setInterval(check_ajax_call_count,100);

Vous pouvez maintenant parcourir window.ajax_call_count dans la partie succès de vos demandes ajax jusqu'à ce qu'elle atteigne le nombre spécifié d'appels envoyés (window.ajax_calls_completed).

1
arunzer

Je n’ai pas encore essayé, mais c’est la meilleure façon de penser si j’ai un nombre considérable d’appels en ajax.

Méthode 1:

let ajax1= $.ajax({url:'', type:'', . . .});
let ajax2= $.ajax({url:'', type:'', . . .});
.
.
.
let ajaxList = [ajax1, ajax2, . . .]

let count = 0;
let executeAjax = (i) => {
   $.when(ajaxList[i]).done((data) => {
      //  dataOperations goes here
      return i++
   })
}
while (count< ajaxList.length) {
   count = executeAjax(count)
}

S'il n'y en a qu'une poignée, vous pouvez toujours les imbriquer comme ceci.

Méthode 2:

$.when(ajax1).done((data1) => {
      //  dataOperations goes here on data1
      $.when(ajax2).done((data2) => {
         //  Here you can utilize data1 and data 2 simultaneously 
         . . . and so on
      })
   })

Remarque: S'il s'agit d'une tâche répétitive, sélectionnez méthode1 , et si chaque donnée doit être traitée différemment, l'imbrication dans méthode2 est plus logique.

0
adityajain019
$(document).ready(function(){
 $('#category').change(function(){  
  $("#app").fadeOut();
$.ajax({
type: "POST",
url: "themes/ajax.php",
data: "cat="+$(this).val(),
cache: false,
success: function(msg)
    {
    $('#app').fadeIn().html(msg);
    $('#app').change(function(){    
    $("#store").fadeOut();
        $.ajax({
        type: "POST",
        url: "themes/ajax.php",
        data: "app="+$(this).val(),
        cache: false,
        success: function(ms)
            {
            $('#store').fadeIn().html(ms);

            }
            });// second ajAx
        });// second on change


     }// first  ajAx sucess
  });// firs ajAx
 });// firs on change

});
0
Avinash Saini