以下代码获取一个 json 列表,然后对每个列表项执行另一个获取调用以更改它们的值。问题是它不是同步完成的。 “new”在“update”之前打印到控制台。
fetch(API_URL_DIARY)
.then(response => response.json())
.then(data => {
console.log("old", data);
return data;
})
.then(data => {
data.forEach(function(e, index,array) {
fetch(API_URL_FOOD_DETAILS + e.foodid)
.then(response => response.json())
.then(data => {
array[index] = {...e, ...data};
console.log("update");
})
});
console.log("new", data)
});
更新
这是我合并@Andy 解决方案的方式:
function fetchFoodDetails(id, index) {
return fetch(API_URL_FOOD_DETAILS + id)
.then(response => response.json())
.then(data => {
return [index, data];
});
}
function fetchDiary() {
return fetch(API_URL_DIARY)
.then(response => response.json())
.then(data => {
return data;
})
}
(async () => {
const data = await fetchDiary();
console.log("old", JSON.stringify(data));
const promises = data.map((food, index) => fetchFoodDetails(food.id, index));
await Promise.all(promises).then(responses => {
responses.map(response => {
data[response[0]] = {...data[response[0]], ...response[1]};
console.log("update");
})
});
console.log('new', JSON.stringify(data));
})();
这更困难,所以我选择了@connoraworden 的解决方案。但我认为它可以简化。
感谢您的所有回答。
原文由 Username 发布,翻译遵循 CC BY-SA 4.0 许可协议
解决此问题的最佳方法是使用
Promise.all()
和map()
。map 在这种情况下会做什么,返回
fetch
的所有承诺。然后会发生什么
await
将使您的代码执行同步,因为它会等待所有承诺在继续执行之前得到解决。此处使用
forEach
的问题在于,它不会等待异步请求完成,然后才移至下一项。您应该在此处使用的代码是: