我有一个foreach循环,并且正在遍历元素。对于每个元素,我都使用ajax将其保存到数据库中。但是,我希望每次迭代都等到之前的迭代保存到数据库中并收到响应。
让我给你一个简单的例子:
$('#myBtn').click(function() {
let elements = $('.checkboxes:checked');
elements.forEach(function(i, el) {
let id = $(el).data('id');
saveToDatabase(id);
// I want it to pause here until it receives a response from other function
// before going to the next iteration..
})
})
function saveToDatabase(id) {
axios.get('/save-to-db/' + id)
.then(response => {
return true;
}).catch(err => {
return false;
});
}
我希望for {Each}中的元素在从saveToDatabase
函数获得“返回”后移至下一个迭代。
(顺便说一句,我知道这个示例过于简化并且在现实生活中毫无意义,因为我可以将id批量保存到数据库中,但是我只想了解如何处理这种情况)。
答案 0 :(得分:1)
将saveToDatabase(id)
定义为异步函数,在本示例中使用await
。
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
编辑:
另外,从saveToDabase
函数返回promise。
saveToDatabase函数的实现:
$('#myBtn').click(function() {
let elements = $('.checkboxes:checked');
for (let element of elements) {
await saveToDatabase(id);
}
})
async function saveToDatabase(id) {
return axios.get('/save-to-db/' + id)
.then(response => {
return true;
}).catch(err => {
return false;
});
}
我也忘记了: 使用await的函数也需要在其前面具有异步功能。
答案 1 :(得分:1)
由于forEach
使用回调函数,因此很难继续使用它来同步调用。相反,我认为使用简单的for
循环会起作用。
$('#myBtn').click(async () => {
let elements = $('.checkboxes:checked');
for (let element of elements) {
let id = $(element).data('id');
await saveToDatabase(id);
}
});
答案 2 :(得分:0)
有很多方法可以使请求彼此等待。对您来说,最简单的方法是保存最新的请求承诺的引用,以便在上一个已解决的情况下调用下一个请求(在then
函数内部)。
$('#myBtn').click(function() {
let elements = $('.checkboxes:checked');
let previousCall = Promise.resolve();
elements.forEach(function(i, el) {
let id = $(el).data('id');
previousCall = previousCall.then(() => saveToDatabase(id));
// I want it to pause here until it receives a response from other function
// before going to the next iteration..
})
})
function saveToDatabase(id) {
return axios.get('/save-to-db/' + id)
.then(response => {
return true;
}).catch(err => {
return false;
});
}