我有一个
$.each
循环,它在另一个 $.each
中,它正在调用一个函数来向我的后端系统添加值。
我的
$.each
循环是这样的:
$.each(locations, function( i, location ) {
$.each(location, function( i, site ) {
addsite ( site.url, site.address, site.zip, site.contact, site.id )
})
})
当我直接调用函数
addsites
时,而不是从 $.each
循环中它按预期工作,但是当从 $.each
循环中调用时它工作,但有时代码在其他代码完成之前被调用。
经过大量测试,我发现这是由于
$.ajax
被调用,这显然在其他代码运行之前没有完成。
我的工作职能是:
function addsite( url, address, zip, contact, id ) {
// 1. lots of jquery
// 2. lots of jquery
$.ajax({ type: "POST",
url: url,
cache: false,
complete : function(text) {
console.log ( '3.' + text )
}
});
// 4. more jquery
})
我在第 1、2、3 和 4 点添加了调试,可以看到 1. 和 2. 中的所有内容都被正确调用,但是 4. 中的代码在
$.ajax
完成之前正在运行。
在
$.each
循环中调用该函数时,我在 console.log 中多次看到 1、2、4,后面跟着多个 3,因为它稍后会完成。这需要作为 1,2,3,4 运行。
我明白为什么会发生这种情况,并且发现将
async: false
添加到 $.ajax
允许这个工作,但它已经贬值所以我试图找到更好的方法。
我需要对
$.each
循环或addsite
函数做些什么吗?如果它是函数,我需要确保它在直接调用时有效,而不仅仅是从$.each
循环调用。
有人可以建议我如何才能让它正常工作。
谢谢
根据您的理解标准稍微更新一下代码:
$.each(locations, function( i, location ) {
$.each(location, function( i, site ) {
addsite ( site.url, site.address, site.zip, site.contact, site.id, function() {
console.log("AJAX request complete for " + site.id);
});
});
});
也在这个fn
function addsite( url, address, zip, contact, id, callback ) {
$.ajax({
type: "POST",
url: url,
cache: false,
complete : function(text) {
console.log ( text );
callback();
}
});
}
试试这个..
您可以使用 Promise 来确保 addsite 函数中的代码以正确的顺序运行。除了使用
complete
的 $.ajax
回调,您还可以返回一个 Promise,它会在 AJAX 调用完成时解析。然后,您可以使用 Promise.all
等待所有 AJAX 调用完成,然后再继续其余代码。
function addsite( url, address, zip, contact, id ) {
// Return a Promise that resolves when the AJAX call is complete
return new Promise(function(resolve, reject) {
// lots of jquery
$.ajax({
type: "POST",
url: url,
cache: false,
success: function(response) {
// Call resolve() when the AJAX call is successful
resolve(response);
},
error: function(xhr, status, error) {
// Call reject() when the AJAX call fails
reject(error);
}
});
// more jquery
});
}
然后您可以使用 Promise.all 等待所有 AJAX 调用完成:
var promises = [];
$.each(locations, function( i, location ) {
$.each(location, function( i, site ) {
// Add the Promise returned by addsite to the promises array
promises.push(addsite(site.url, site.address, site.zip, site.contact, site.id));
})
});
// Wait for all of the Promises to resolve before continuing
Promise.all(promises).then(function() {
console.log("All AJAX calls complete");
}).catch(function(error) {
console.log("An error occurred:", error);
});
很抱歉,我没有立即看到它不能在ajax请求中使用
async: false
现在在
for of
上重做循环并添加async await
,做了一个测试用例:
const locations = [
[
{id: 1},
{id: 2}
],
[
{id: 3},
{id: 4}
]
];
const addsite = async( url, address, zip, contact, id ) => {
console.log('before');
await $.ajax({
type: 'POST',
url: 'https://www.boredapi.com/api/activity',
cache: false,
complete : function(text) {
console.log(id);
}
});
console.log('after');
}
(async () => {
for (let location of locations) {
for (let site of location) {
await addsite(site.url, site.address, site.zip, site.contact, site.id);
}
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>