背景
代码如下:
const res1 = await getOrderPackage({
XM_LX: "95", // 入院检查套餐
});
const res2 = await getOrderPackage({
XM_LX: "98", // 入院检验套餐
});
const res = [...res1.data, ...res2.data]
let retList: any[] = [];
const map: Map<String, IOrderPackageDetail[]> = new Map();
res.forEach(async (e) => {
const childRes = await getOrderPackageDetail({
PACKAGE_ID: e.PACKAGE_ID,
});
map.set(e.PACKAGE_NAME, childRes.data);
})
console.log("map => ", map)
console.log("map.size => ", map.size)
运行结果:
原理分析
这段代码存在一个问题,即在使用 forEach 方法时,无法正常地处理异步操作和等待结果返回
forEach 方法本身是同步的,它不会再迭代过程中等待异步操作完成。在这段代码中,通过在 forEach 回调函数中使用 async 和 await 来尝试处理异步操作。然而,这并不会按照预期地工作。
forEach 方法不会等待异步操作完成,所以在 forEach 回调函数中使用 await 并不能保证在每个异步操作执行完成后在执行下一次循环。这意味着 map 的设置操作会在异步操作执行之前就已经完成,并且 map.size 可能为零,因为异步操作尚未完成。
解决问题
为了解决这个问题,可以使用 for…of循环 或 for循环来确保异步操作的按顺序执行,并等待所有异步操作完成后再执行后续逻辑。
const res1 = await getOrderPackage({
XM_LX: "95", // 入院检查套餐
});
const res2 = await getOrderPackage({
XM_LX: "98", // 入院检验套餐
});
const res = [...res1.data, ...res2.data]
let retList: any[] = [];
const map: Map<String, IOrderPackageDetail[]> = new Map();
for (let i = 0, len = res.length; i < len; i++) {
const childRes = await getOrderPackageDetail({
PACKAGE_ID: res[i].PACKAGE_ID,
});
map.set(res[i].PACKAGE_NAME, childRes.data);
}
console.log("map => ", map)
console.log("map.size => ", map.size)