javascript - For循环和地图差异
问题描述
我有两个案例,我试图了解发生了什么,但对我来说仍然不够清楚,所以我读到如果我想在 for 循环或 map 中运行异步调用,我需要使用 Promise.all 但让我分享发生了什么与我一起
首先,我使用 map 更新数据库中的许多记录,它更新了一些而不是全部数据
AllAuthToken.map(async singleToken =>{
let deviceIds = uuidv4();
let newDeviceArray = {
[deviceIds]: singleToken.deviceToken,
};
await AuthToken.updateOne(
{ _id: singleToken._id },
{
$set: {
tokensDeviceArray: [newDeviceArray],
deviceId: [deviceIds],
},
},
{ $new: true }
);
}
然后发生这种情况后,我使用了 for 循环并更新了所有数据
for (let i = 0; i < AllAuthToken.length; i++) {
let deviceIds = uuidv4();
let newDeviceArray = {
[deviceIds]: AllAuthToken[i].deviceToken,
};
await AuthToken.updateOne(
{ _id: AllAuthToken[i]._id },
{
$set: {
tokensDeviceArray: [newDeviceArray],
deviceId: [deviceIds],
},
},
{ $new: true }
);
}
那么发生了什么导致第一个案例失败而第二个案例通过
解决方案
原因是.map
它一个接一个地执行它的回调而不等待。做它的await
事,但这只会延迟之后的代码await
。但它不会阻止.map
迭代继续下一次调用回调,因为它不是发生的async
函数的一部分await
。
for
另一方面,循环是与发生的地方相同的函数的一部分,因此 async
迭代await
仅在等待的承诺解决时才会继续。
如果您希望以“并行”方式执行数据库请求,即在不等待前一个请求解决的情况下启动下一个请求,则使用Promise.all
,如下所示:
let promises = AllAuthToken.map(singleToken => {
let deviceIds = uuidv4();
let newDeviceArray = {
[deviceIds]: singleToken.deviceToken,
};
return AuthToken.updateOne(
{ _id: singleToken._id },
{
$set: {
tokensDeviceArray: [newDeviceArray],
deviceId: [deviceIds],
},
},
{ $new: true }
);
};
await Promise.all(promises);
/* ... now all is done ... */
推荐阅读
- reactjs - 提交后对清除表单字段做出反应
- android - Android 11 上的 WebView - 不显示本地图像文件
- python - 如何在 Django 中表示一类现有的 python api?
- php - joomla 上的帖子的白屏
- java - Spark Java 在虚拟文件位置提供静态文件
- python-3.x - 如果数字在列表中重复,则返回 true
- flutter - Flutter Navigator.pop(context) 不起作用
- excel - 使用 Excel vba 在 Investing.com 投资组合中进行网页抓取
- python - 无法使用 Python 的 Beautiful Soup 从特定的 span 标签中提取文本
- git - 如何使用命令行 git 接受来自 Github 的拉取请求(PR)