成功堆叠多个AJAX请求(jQuery)

时间:2014-07-18 08:59:28

标签: javascript jquery ajax queue

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

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

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

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

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

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

问题如下:

  1. 是否可以调用相同的脚本两次
  2. 是否有一种有效的方法可以避免在其他ajax请求之前执行ajax请求?
  3. 在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请求正确执行,第二个AJAX请求也正确执行,但在第三个AJAX请求中(data: {'action':'create>day', 'date': rs, 'sqltable': createInfo})请求被触发但缺少上面定义的参数rs。

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

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

    此外,我将在本地使用此脚本,因此延迟或与服务器和客户端引起的延迟相关的每个问题都不重要。

    上次请求是否有任何理由不能使用异步请求?如果有的话,这个案子有一个有价值的解决方案?我还检查了有关队列的主题,但它也没有解决我的问题。由于某些原因,异步,最后的AJAX请求只是被部分触发,因为变量rs没有正确传递。

1 个答案:

答案 0 :(得分:2)

一种解决方案是使用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);
                                    }
                                });
                        }
                    }
                });
    };
}