For 循环和 map diff

For loop and map diff

我有两个案例,我试图了解发生了什么,但我还是不够清楚,所以我读到如果我想 运行 异步调用 for 循环或映射我需要使用Promise.all 但让我分享一下发生在我身上的事情

首先我用地图更新了我数据库中的许多记录,它更新了一些而不是全部数据

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 迭代继续回调的下一次调用,因为它不是 await 发生的 async 函数的一部分。

另一方面,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 ... */