【问题标题】:jquery how to use multiple ajax calls one after the end of the otherjquery如何在另一个结束后使用多个ajax调用
【发布时间】:2012-03-03 08:41:57
【问题描述】:

我在移动应用中,我使用多个 Ajax 调用从 Web 服务器接收数据,如下所示

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

如何强制第二个 ajax 调用在第一个结束后开始……第三个在第二个结束后开始,依此类推?

【问题讨论】:

  • 唯一的问题是一个失败的 AJAX 调用将导致没有其他 AJAX 调用被进行(因为没有“如果 AJAX 调用失败则执行此操作”,它只会等待一个“成功”永远)。也许这正是您想要的……只是需要考虑的事情。
  • 我认为你最好按照@Lyon 的建议使用 $.when。

标签: jquery function get jsonp


【解决方案1】:

将它们放在它所依赖的success: 中。

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

        // do stuff

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

【讨论】:

  • 我该怎么做你能解释一下
  • 重复多个级别的$.ajax() 调用。
  • 您可以对未知数量的 AJAX 请求递归地执行此操作。目前有几个答案可以证明这一点。
  • 递归绝对是要走的路……假设他每次都在做完全相同的调用。我只是没有假设。
  • @timothy - 如果我将写作作为一种常用方法。这种情况怎么称呼?
【解决方案2】:

您有点接近,但您应该将您的函数放在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 年 8 月 21 日更新了有关 cmets 的优点。

【讨论】:

  • 神圣的阿贾克斯,蝙蝠侠!这肯定是 OP 需要的过度复杂化。 @Lyon 的回答要好得多。
  • 另外,如果你想忽略错误,你可以在那里写一个complete: function(){ current++; do_ajax();}。 :)
  • 为什么会获得如此多的选票?这是“递归”AJAX 回调的一个示例。 OP 询问“连续”回调...明确 not 调用 same 函数。
【解决方案3】:

这是我使用了一段时间的最优雅的解决方案。它不需要外部计数器变量,并且提供了很好的封装程度。

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

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

ajaxRequest(urls); 

【讨论】:

  • 这是优雅的if,除了 URL 之外,每个调用都是相同的。如果 Ajax 调用涉及不同的方法、返回处理和/或要发送的不同数据,那么它会变得非常不优雅。在这种情况下,Skyler 的上述解决方案会更加清晰。
  • 这只是一个基本示例,但您可以以类似的方式为每个请求定义方法、返回处理和参数.. 要有创意.. 但是对于初学者来说,为每个请求定义新函数可能更直接向前接近..
  • 使用 ajax 配置对象数组代替字符串数组。将 ajaxRequest 和 list 封装在里面,并在调用 ajax 请求之前添加上下文属性。想知道是否可以修改为调用多个 ajax 请求但同时运行的固定数量不超过一个。
  • 确实非常优雅!作为通用解决方案,恕我直言,它应该是公认的答案。
【解决方案4】:

将每个 ajax 调用包装在一个命名函数中,然后将它们添加到上一个调用的成功回调中:

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

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

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


callA();

【讨论】:

  • 这让函数名产生误导:callA不仅是callA,也是callB & C
  • callA 可以是 callABC 和 callB -> calBC,但这只有在成功时才有意义。不过,对于小代码来说,这似乎是一个简单的解决方案,而且比公认的答案更直接。
【解决方案5】:

您还可以使用 jquery when 和 then 函数。例如

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

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

【讨论】:

  • 如何写出4级层次?
【解决方案6】:

我认为以下更实用,因为它不会对 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);

现在您可以在 ajax 请求的成功部分中迭代 window.ajax_call_count,直到达到指定的调用发送次数 (window.ajax_calls_completed)。

【讨论】:

    【解决方案7】:

    还没有尝试过,但如果有无数个 ajax 调用,这是我能想到的最好方法。

    方法一:

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

    如果只有少数,你总是可以像这样嵌套它们。

    方法二:

    $.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中会更感觉。

    【讨论】:

    • 我无法理解第一种方法。当您致电 $.ajax(..); 时,它会被调用。是的,它返回承诺,但会尽快执行。不是 OP 要求的,而是如何一个接一个地调用。
    【解决方案8】:
    $(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
    
    });
    

    【讨论】:

      【解决方案9】:

      我们可以简单地使用

      async: false 
      

      这将满足您的需要。

      【讨论】:

      • 不,这是您能做的最糟糕的事情,因为它会挂起您的浏览器,直到 ajax 请求未完成。
      • 从 jQuery 1.8 开始,不推荐使用 async: false 和 jqXHR ($.Deferred)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-05-22
      • 2023-03-03
      • 2022-11-29
      • 1970-01-01
      相关资源
      最近更新 更多