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

2022-01-21 00:00:00 queue jquery javascript ajax

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

I'm just testing a local application and wanted to make something like this:

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

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

Surprisingly, everything is working fine (apart the last point), but I'm getting some troubles.

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

The table gets created and populated but, for some reasons, the very last AJAX requests doesn't fire correctly, since it's not passing a parameter correctly.

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

My ajax requests are ALL asyncronous, if I set them syncronous the whole thing will freeze, but all the requests are executed correctly, even the very last one.

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

For instance, let's say that I don't want to use asyncronous requests in order to DON'T freeze the page and be able to show a progress bar.

问题如下:

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

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

After reading a whole bunch of topics here in stackoverflow, I edited my code and tried to:

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

此时,我还有一个问题:

At this point, I still have another question:

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

By stacking AJAX requests, is it actually TRUE that everything executed into the "success" callback will be executed AFTER the ajax requests has completed?

这就是我正在表演的:

$.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>day', 'date': rs, 'sqltable': createInfo}) 被触发但缺少上面定义的参数 rs.

the first AJAX request executes correctly, the second one does too, but in the third one (the one with data: {'action':'create>day', 'date': rs, 'sqltable': createInfo}) is getting fired but is missing the parameter rs defined above.

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

Also, to be clearer, rs is a temporary variable I've defined when I was trying to make the requests outside the "success" callback and when using $.when and $.done, in this case the variable rs is useless, but It won't change anything.

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

Again, as said above, the whole thing works using a syncronous request, but doesn't by using an asyncronous one.

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

Moreover, I'm just going to use this script locally, so delays or every problematic related to delays caused by servers and client are not important.

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

Is there any reason for the last request to don't work with an asyncronous request? if so is there a valuable solution for this case? I've also checked the topics about the queue, but it didn't solve my problem either. For some reasons, asyncronously, the last AJAX requests get just partially fired, since the variable rs is not getting passed correctly.

推荐答案

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

One solution is to use queue() function. This way you can execute as many functions as you want

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

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

Then your functions have no need of shared vars, with the concurrency conflicts that it causes.

应该是这样的:

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

相关文章