【问题标题】:Stacking multiple AJAX requests on success (jQuery)成功堆叠多个 AJAX 请求(jQuery)
【发布时间】:2014-07-18 08:59:28
【问题描述】:

我只是在测试一个本地应用程序并想做这样的事情:

  • 点击按钮,很简单。
  • 执行 AJAX 请求并创建数据库表。
  • 创建表后,执行另一系列 AJAX 请求并根据从一系列选择框中获取的一些参数填充表。
  • 使用进度条“动画化”整个事物。

令人惊讶的是,一切正常(除了最后一点),但我遇到了一些麻烦。

表已创建并填充,但由于某些原因,最后的 AJAX 请求没有正确触发,因为它没有正确传递参数。

我的 ajax 请求都是异步的,如果我将它们设置为同步,整个事情都会冻结,但所有请求都正确执行,即使是最后一个。

例如,假设我不想使用异步请求来不冻结页面并能够显示进度条。

问题如下:

  1. 是否可以调用同一个脚本两次
  2. 有没有一种有效的方法来避免 ajax 请求在其他 ajax 请求之前执行?

在 stackoverflow 中阅读了一大堆主题后,我编辑了我的代码并尝试:

  • 使用 jQuery.AJAX 原型代替 jQuery.POST
  • 异步设置所有内容,以免页面冻结并能够处理进度条
  • 在父 AJAX 请求的“成功”回调中执行下一个 AJAX 请求。

此时,我还有一个问题:

通过堆叠 AJAX 请求,在“成功”回调中执行的所有内容是否真的会在 ajax 请求完成后执行?

这就是我正在表演的:

$.ajax({
        type: "POST",
        url: '../libs/php libraries/agenda.php',
        data: {'action':'create>agenda', 'sqlname': createInfo},
        processData: true,
        dataType: "json",
        timeout: 60000,
        async: true,
        success: function(res) {
            $('#popup_content').append(res.log);
            var dateList = new Array();
            var dateObj = new Date();

            var m = dateObj.getMonth();
            var Y = dateObj.getFullYear();
            for (var i = 1; i <= 31; i++) {
                dateList.push(i+"/"+m+"/"+Y);
            }

            for (var i = 0; i < dateList.length; i++) {
                var rs = false;
                    $.ajax({
                        type: 'POST',
                        url: '../libs/php libraries/agenda.php',
                        data: {'action':'validate>date', 'date': dateList[i]},
                        processData: true,
                        timeout: 60000,
                        async: true,
                        dataType: "json",
                        success: function(x) {
                                $('#popup_content').append(x.log);
                                if (x.res == 'true') {
                                    rs = dateList[i];
                                }

                                if (rs != false) {
                                        $.ajax({
                                            type: 'POST',
                                            url: '../libs/php libraries/agenda.php',
                                            data: {'action':'create>day', 'date': rs, 'sqltable': createInfo},
                                            processData: true,
                                            timeout: 60000,
                                            async: true,
                                            dataType: "json",
                                            success: function(newResult) {
                                                console.log(newResult.res);
                                                        $('#popup_content').append(newResult.log);
                                            }
                                        });
                                }
                            }
                        });

            }
        }
    });

第一个 AJAX 请求正确执行,第二个也正确执行,但在第三个(带有 data: {'action':'create&gt;day', 'date': rs, 'sqltable': createInfo} 的请求)中被触发但缺少上面定义的参数 rs。

另外,更清楚地说,rs 是我在尝试在“成功”回调之外发出请求以及使用 $.when 和 $.done 时定义的临时变量,在这种情况下,变量 rs 是没用,但它不会改变任何东西。

再次,如上所述,整个事情使用同步请求,但不使用异步请求。

而且,我只是在本地使用这个脚本,所以延迟或与服务器和客户端导致的延迟相关的每个问题都不重要。

最后一个请求不能处理异步请求有什么原因吗?如果是这样,这种情况是否有有价值的解决方案?我还检查了有关队列的主题,但它也没有解决我的问题。由于某些原因,异步地,最后的 AJAX 请求只是被部分触发,因为变量 rs 没有正确传递。

【问题讨论】:

    标签: javascript jquery ajax queue


    【解决方案1】:

    一种解决方案是使用 queue() 函数。这样你可以执行任意数量的函数

        var ajaxQueue = $({});
    
    
        $.ajaxQueue =  function(date, ajaxOpts) {  
    
            // queue the method. a second call wont execute until this dequeues
            ajaxQueue.queue(function(next) {
                // for this example I serialize params, but you can save them in several variables 
                // and concat into ajaxOpts.data
                var params = method_that_get_params_and_serialize_them();
                ajaxOpts.data = params;      
    
                ajaxOpts.complete = function() {       
                    next();
                };
    
                $.ajax(ajaxOpts);
            });
        };
    

    那么你的函数不需要共享变量,因为它会导致并发冲突。

    应该是这样的:

    $.ajax({
        type: "POST",
        url: '../libs/php libraries/agenda.php',
        data: {'action':'create>agenda', 'sqlname': createInfo},
        processData: true,
        dataType: "json",
        timeout: 60000,
        async: true,
        success: function(res) {
            $('#popup_content').append(res.log);
            var dateList = new Array();
            var dateObj = new Date();
    
            var m = dateObj.getMonth();
            var Y = dateObj.getFullYear();
            for (var i = 1; i <= 31; i++) {
                dateList.push(i+"/"+m+"/"+Y);
            }
    
            for (var i = 0; i < dateList.length; i++) {                
                    processDate(dateList[i]);
    
            }
        }
    });
    
    function processDate(date){   
    
        $.ajaxQueue({
                    type: 'POST',
                    url: '../libs/php libraries/agenda.php',
                    data: {'action':'validate>date', 'date': date},
                    processData: true,
                    timeout: 60000,
                    async: true,
                    dataType: "json",
                    success: function(x) {
                            $('#popup_content').append(x.log);
                            if (x.res == 'true') {
                                    $.ajax({
                                        type: 'POST',
                                        url: '../libs/php libraries/agenda.php',
                                        data: {'action':'create>day', 'date': date, 'sqltable': createInfo},
                                        processData: true,
                                        timeout: 60000,
                                        async: true,
                                        dataType: "json",
                                        success: function(newResult) {
                                            console.log(newResult.res);
                                                    $('#popup_content').append(newResult.log);
                                        }
                                    });
                            }
                        }
                    });
        };
    }
    

    【讨论】:

    • 谢谢,但它仍然没有执行最后一个 AJAX 请求,它仍然没有获取日期参数(它是 dateList[i],而不是 rs)。
    • 问题出在 "i" var 中,在 for 循环中您同时进行 ajax 调用,并且在第一次成功回调时,i 是 dateList.lenght,因此 dateList[i] 未定义。我已经编辑了解决方案来解决这个问题
    • 谢谢,我实际上想出了一个与您编辑的完全不同的解决方案,但无论如何它都非常相似。为了不必在全局变量中存储值,我决定更进一步,让我的 PHP 脚本能够返回所需的值。无论如何,它现在正在工作,会发生一些延迟,但没关系。谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2011-09-26
    • 2013-03-20
    • 2016-12-28
    相关资源
    最近更新 更多