【问题标题】:How to do multiple ajax calls and update the ui after each one如何进行多次ajax调用并在每次调用后更新ui
【发布时间】:2013-05-30 15:08:32
【问题描述】:

我正在为一些大型查询编写脚本并避免 php 端超时,加上给用户一些输入,我试图在 jquery 上完成大部分工作。

所以它的工作原理是这样的:首先,用户在选择中选择一条记录。当他点击按钮时,我收到了一个 ajax 调用,以便从 json 格式的记录中获取我需要的详细信息。

有了响应,我得到了一个循环,该循环对第一次调用的每个结果进行 ajax 调用。

如果我将 async 设置为 false,它可以工作,但浏览器会因为有多个 ajax 调用而冻结。那么有没有办法在关闭异步的情况下更新 ui?

我的意思是,当我在循环中进行 ajax 调用时,我需要将 async 设置为 off,这对我来说没有任何意义。它可以同时进行多个调用,我对此很好,但是为什么除非我将 async 设置为 false,否则它不会在该循环中获取当前索引?它继续使用第一个索引。

    $("#button_copy").live('click', function(){
        $('#button_copy').attr("disabled", true);
        id = $('#select').val();
        $.ajax({
            type: "POST",
            url: "query1.php",
            dataType: 'json',
            async:false,
            cache: false,
            data: 'id=' + id,
            success: function( data ) {
                var total1 = data['records'].length;
                $("#console").append('Total query 1: ' + total1 + '<br />');
                for (var i in data['records']) {
                    $.ajax({
                        type: "POST",
                        url: "query2.php",
                        dataType: 'json',
                        async:false,
                        cache: false,
                        data: 'id=' + data['records'][i].id,
                        success: function( data2 ) {
                            var total2 = data2['records2'].length;
                            $("#console").append('Total of query 2 from ' + data['records'][i].person + ': ' + total2 + '<br />');
                        },
                        error: function(data2) {
                            console.log(data2);
                        }
                    });
                    var percentprogress1 = (i / total1) * 10000;
                    $('#progressbar1').css('width',percentprogress1 + '%');
                }
            },
            error: function(data) {
                console.log(data);
            }
        });
    });

【问题讨论】:

  • 将循环更改为 for(var i=0; i
  • 当我这样做时,看起来它甚至没有得到数组上的 [0]。我改为 i=1;
  • 你应该只使用一个 ajax 请求来返回所有结果一次

标签: jquery ajax asynchronous


【解决方案1】:

您会遇到问题,因为您尝试在回调中使用 i,但在调用回调时 i 不再具有其原始值。你也不应该在数组上使用for ... in - 只在对象上。

我建议不要使用任何类型的 for 循环,而是在前一个完成时触发每个连续的 AJAX 调用:

$.ajax(...).done(function(data) {

    var all = data.records;
    (function next() {
        var record = all.shift();
        if (record) {
            $.post(...).done(next, function(res) {
                // process inner result
                // update UI, etc
                ...
            });
        }
    })();       // invoke immediately

});

请注意,我使用“延迟”语法,而不是在两个 AJAX 调用中传递 success: 处理程序。

在“伪递归”循环中注意,我使用了.done(next, ...),它允许循环并行开始下一个 AJAX 调用,同时处理当前调用的结果。

【讨论】:

    【解决方案2】:

    我自己也遇到了类似的问题。我在 while 循环中运行了一系列 ajax 请求。有些电话没有被打!它杀了我!我的结论是我的浏览器——谷歌浏览器——忽略了“重复”请求。

    看看这个伪代码:

    while (i < ajaxCallArray.length) {
        currentAjaxObject = ajaxCallArray[i];
        ajaxPost = $.post(currentAjaxObject.url, function(data) {
        //response data needs to go into a function such that each request gets its own "data" variable created.otherwise it just overwrites data!!
        processAjaxResponse(data, currentAjaxObject);
            },"json");
    i++;
    }
    

    如果 ajaxCallArray[0].url = "http://www.google.com"ajaxCallArray[1].url = "http://www.google.com"ajaxCallArray[2].url = "http://www.google.com" 浏览器实际上只会进行 1 次调用!!

    解决办法: 即使您不使用这些 url 参数,您也必须执行 ajaxCallArray[0].url = "http://www.google.com?count=0"ajaxCallArray[1].url = "http://www.google.com?count=0"ajaxCallArray[2].url = "http://www.google.com?count=0" 之类的操作,只需添加一些内容以使它们与众不同。这样浏览器将处理所有调用,即使它们是立即完成的。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      相关资源
      最近更新 更多