Как использовать несколько вызовов AJAX один за другим конец? - PullRequest
37 голосов
/ 11 февраля 2012

Я в мобильном приложении и использую несколько вызовов Ajax для получения данных с веб-сервера, как показано ниже

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
        });
    });
}

Как я могу заставить 2-ой вызов ajax начинаться после окончания первого ... 3-го после конца 2-го и так далее?

Ответы [ 9 ]

51 голосов
/ 11 февраля 2012

Вы несколько близки, но вы должны поместить свою функцию в обработчик событий document.ready вместо обратного.

Еще один способ сделать это - поместить вызов AJAX в обобщенную функцию и вызвать эту функцию из обратного вызова AJAX, чтобы выполнить цикл по набору запросов в следующем порядке:

$(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();

});

В этом примере рекурсивный вызов для запуска следующего AJAX-запроса устанавливается как обратный вызов complete, поэтому он выполняется независимо от состояния текущего ответа. Это означает, что если запрос истекает или возвращает ошибку HTTP (или неверный ответ), следующий запрос все равно будет выполнен. Если вы требуете, чтобы последующие запросы выполнялись только тогда, когда запрос был успешным, тогда лучше использовать обратный вызов success для выполнения рекурсивного вызова.

Обновлено 2018-08-21 в отношении хороших моментов в комментариях.

47 голосов
/ 11 февраля 2012

Поместите их внутрь success: того, на которое оно опирается.

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

        // do stuff

        // call next ajax function
        $.ajax({ xxx });
    }
});
10 голосов
/ 11 февраля 2012

Оберните каждый вызов ajax в именованную функцию и просто добавьте их к обратным вызовам успеха предыдущего вызова:

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

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

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


callA();
9 голосов
/ 19 января 2017

Это самое элегантное решение, которое я использовал некоторое время. Для него не требуется переменная внешнего счетчика, и он обеспечивает хорошую степень инкапсуляции.

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

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

ajaxRequest(urls); 
8 голосов
/ 13 апреля 2014

Вы также можете использовать jquery, когда и затем функции.например

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

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

2 голосов
/ 11 января 2015

Я считаю следующее более прагматичным, так как оно не упорядочивает вызовы ajax, но это, безусловно, вопрос вкуса.

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);

Теперь вы можете перебирать window.ajax_call_count внутри успешной части ваших запросов ajax до тех пор, пока не будет достигнуто указанное количество отправленных вызовов (window.ajax_calls_completed).

0 голосов
/ 25 октября 2018

Еще не пробовал, но это лучший способ, который я могу себе представить, если существует множество вызовов ajax.

Method1:

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)
}

Если есть только горстка, вы всегда можете вложить их следующим образом.

Method2:

$.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
      })
   })

Примечание: Если это повторяющаяся задачаперейдите к method1 , и, если все данные должны обрабатываться по-разному, вложенность в method2 имеет больше смысла.

0 голосов
/ 05 апреля 2017

Мы можем просто использовать

async: false 

Это сделает вашу нужду.

0 голосов
/ 03 апреля 2013
$(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

});
...