首页 > 解决方案 > JavaScript:如何按特定顺序运行 AJAX 查询,等待某些调用完成后再继续

问题描述

代码如下,我面临的问题也是如此。首先是我想要发生的事情:

这将是理想的结果

运行这一请求

/cc/AjaxController/justTheSplit/normal

完成这一请求后,运行以下命令

/cc/AjaxController/workCsv/0/normal
...
/cc/AjaxController/workCsv/100/normal

在所有 101 都运行后,运行以下命令

/cc/AjaxController/sortHours/0/normal
...
/cc/AjaxController/sortHours/100/normal

在所有 101 都运行后,运行以下命令

/cc/AjaxController/workFilters/0/normal
...
/cc/AjaxController/workFilters/100/normal

在所有 101 都运行之后,去做同样的事情,但是对于异常,然后是向导

全部运行后,运行最后一个 Ajax 请求

代码

function processData() {
    const types = {1:"normal", 2:"abnormal", 3:"wizard"};
    for (let [key, ty] of Object.entries(types)) {
        var days = 101;
        var i;
        var x = -1;
        var y = -1;
        var z = -1;

        $.get('/cc/AjaxController/justTheSplit/'+ty, function(data, status) {
            for (i=0;i<days;i++) {
                $('.days-progress-'+ty).show();
                $.get('/cc/AjaxController/workCsv/'+i+'/'+ty, function(data, status) {
                    $('.days-progress-'+ty).find('.progress-bar').css('width', i+'%');
                    x++;
                    $.get('/cc/AjaxController/sortHours/'+x+'/'+ty, function(data, status) {
                        y++;
                        $('.hours-progress-'+ty).find('.progress-bar').css('width', (y+1)+'%');
                        $.get('/cc/AjaxController/workFilters/'+y+'/'+ty, function(data, status) {
                            z++;
                            $('.filters-progress-'+ty).find('.progress-bar').css('width', (z+1)+'%');
                            if (z===100 && y===100 && z===100 && ty==='rocu') {
                                $.get('/cc/AjaxController/cleanData', function(data, status) {
                                });
                            }
                        });
                    });

                });
            }
        });
    }
}

我遇到的问题是:

标签: javascriptjqueryajax

解决方案


您可以在函数中使用此代码(或用链async扩展awaits )then

const calls = ['normal', 'abnormal', 'wizard']
const range = Array.from({length:101},(v,k)=>k) // build number array

let build = (url) => calls.flatMap( x => range.map(y => $.get(url + y +'/' + x))) // generates the 303 ajax requests

let init = calls.map(x => $.get('/cc/AjaxController/justTheSplit/' + x)) // generate initial requests
await $.when(...init) // wait all to finish

let step1 = build('/cc/AjaxController/workCsv/')
await $.when(...step1)

let step2 = build('/cc/AjaxController/sortHours/')
await $.when(...step2)

let step3 = build('/cc/AjaxController/workFilters/')
await $.when(...step3)

注意:每一步的所有 303 请求都将并行运行,由浏览器调度并被服务器接受。但是下一步只有在上一步完成后才构建并开始。使用这种方法可以轻松添加更多步骤。当然,您应该try-catch在代码周围添加。

进度条在这里毫无意义。无论如何,您可以将done处理程序附加到函数中的每个单独的请求,该build函数通过计算已完成的请求来进行一些视觉反馈 - 这不会改变其余代码。在等待每个步骤时,您也可以在步骤之间添加进度反馈。


推荐阅读