我有一堆文件要遍历。对于每个文件,根据某些字段值的不同,我可能会或可能不需要发出异步AJAX请求来获取其他数据。在所有这些请求都解决之后,我想将该文件的相关数据附加到网页上,然后再继续下一个文件。我的实际代码包含不相关的信息,但逻辑类似于以下伪代码:
var chain = $.when();
for(x = 0; x < files.length; x++) {
console.log('FOO');
chain = chain.then(function() {
var fieldNamePromises = [];
var fieldName2Promises = [];
if ('fieldName' in files[x]) {
//getFieldNameData returns an AJAX request
fieldNamePromises.push(getFieldNameData())
}
if ('fieldName2' in files[x]) {
//getField2NameData returns an AJAX request
fieldName2Promises.push(getFieldName2Data())
}
Promise.all(fieldNamePromises.concat(fieldName2Promises)).then(function() {
console.log('BAR');
})
});
}
对我来说,这将记录:
'FOO'
'FOO'
'FOO'
'BAR'
'BAR'
'BAR'
我想要的地方:
'FOO'
'BAR'
'FOO'
'BAR'
'FOO'
'BAR'
在继续循环之前,如何强制它等待所有异步请求完成?
以下代码还会产生三个FOO,然后是三个BAR,而不是交替出现FOO BAR。
getFileHistory(fileNumber, function (files) {
var chain = $.when();
for (let x = 0; x < files.length; x++) {
chain = chain.then(function () {
console.log('FOO');
var fieldNamePromises = [];
fieldNamePromises.push(getData('Data', function () { }))
fieldNamePromises.push(getData('Data', function () { }))
return Promise.all(fieldNamePromises).then(function () {
console.log('BAR');
})
});
}
});
function getFileHistory(fileNumber, callback) {
var url = window.baseUrl + "api/get-file-history/filter?fileNumber=" + fileNumber;
return $.ajax({
type: 'GET',
url: url,
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (result) {
callback(result);
}
});
}
function getData(id, callback) {
var url = "api/" + id;
return $.ajax({
type: 'GET',
url: url,
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (result) {
callback(result);
},
error: function (error) {
console.log(error);
}
});
}
更新:当我从getFileHistory(另一个AJAX调用)中删除循环时,它按预期返回FOO / BAR。不确定为什么会有所作为。
答案 0 :(得分:0)
尝试为其创建另一个函数,如下所示
async function(){
var chain = $.when();
for(x = 0; x < files.length; x++) {
console.log('FOO');
chain = await chain.then(async() => {
var fieldNamePromises = [];
var fieldName2Promises = [];
if ('fieldName' in files[x]) {
//getFieldNameData returns an AJAX request
fieldNamePromises.push(getFieldNameData())
}
if ('fieldName2' in files[x]) {
//getField2NameData returns an AJAX request
fieldName2Promises.push(getFieldName2Data())
}
await Promise.all(fieldNamePromises.concat(fieldName2Promises)).then(function() {
console.log('BAR');
})
});
}
}