javascript - 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) {
});
}
});
});
});
}
});
}
}
我遇到的问题是:
- x,y 和 z 的值永远不会被重置,因此它们会上升到 303
- Ajax 请求似乎没有等待前一个请求完成,然后再进入下一批
解决方案
您可以在函数中使用此代码(或用链async
扩展await
s )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
函数通过计算已完成的请求来进行一些视觉反馈 - 这不会改变其余代码。在等待每个步骤时,您也可以在步骤之间添加进度反馈。