我在异步函数中有一个forEach循环,而在forEach中有另外两个执行AJAX请求的forEach循环。一旦所有的AJAX请求都完成,我想返回一个已解决的promise。
首先,用户点击“提交”,我调用一个函数来处理提交,将submitting
属性设置为true
。提交完成后,我想更改submitting
属性的值。
submit() {
this.submitting = true;
if (creating) {
this.create().then(() => this.submitting = false)
}
}
以下是create()
方法的近似值:
async create() {
// Calls a function that uses axios to send a POST request to create
// a new group, returning its ID upon completion. This works fine.
const groupId = await this.createGroup();
// 'users' is an array of objects
this.users.forEach(async user => {
// Create a new user and get their ID. This works fine.
const userId = await this.createUser(info);
// Each 'user' object contains a key called 'attributes' whose
// value is an array of 'attribute' objects. I use axios to make a
// POST request to store the info about these attributes in the DB.
user.attributes.forEach(attribute => {
axios.post('/attributes', attribute)
// In my application, I'm actually calling a method that handles
// making the request, so it looks more like this:
// this.createAttributes(attribute)
}
// Each 'user' object also contains a key called 'images' whose
// value is an array of 'image' objects. Here again, I use axios to
// make a POST request to store the info about these images.
user.images.forEach(image => {
axios.post('/images', image)
}
}
// Once everything has successfully posted, I want to return a
// resolved promise so that the then() callback on my create method
// is executed. However, anything here gets executed before the AJAX
// requests complete.
console.log('All done');
}
我尝试了一些不同的解决方案,我使用map()
捕获承诺,并在完成后使用Promise.all执行回调,但我没有成功。我认为这个问题源于我有多个嵌套的forEach()
循环,但是我不明白承诺(以及它们在forEach()
循环中的行为),以便确定。
我的理解是我可以在await
循环中使用for...of
,但如果可能的话,我宁愿并行执行AJAX请求。
谢谢!
编辑:建议的副本类似,但我的问题是关于嵌套 forEach
循环中的异步操作。虽然解决方案显示处理这些案例没有什么特别独特的(在父循环和嵌套循环上都做同样的事情),但确定是否是这种情况是提出问题的动机。
答案 0 :(得分:1)
map
承诺,然后使用Promise.all并等待它们:
await Promise.all(user.images.map(image =>
axios.post('/images', image)
));
同样适用于主要的forEach:
await Promise.all(this.users.map(async user => {
//...
}));