Javascript 对于循环和映射差异

Javascript 对于循环和映射差异,javascript,arrays,mongodb,es6-promise,Javascript,Arrays,Mongodb,Es6 Promise,我有两个案例,我试图了解发生了什么,但我仍然不清楚,所以我读到,如果我想运行异步调用for loop或map,我需要使用Promise.all 但让我和大家分享一下发生的事情 首先,我使用map更新数据库中的许多记录,它更新了一些而不是所有的数据 AllAuthToken.map(async singleToken =>{ let deviceIds = uuidv4(); let newDeviceArray = { [device

我有两个案例,我试图了解发生了什么,但我仍然不清楚,所以我读到,如果我想运行异步调用for loop或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 (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 }
    );
  }
之后,我使用for循环,它更新了所有数据

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 (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 }
    );
  }
for(设i=0;i

那么,第一个案例失败了,第二个案例通过了,原因是,
.map
在不等待的情况下一个接一个地执行回调。
await
完成了它的工作,但这只会延迟
await
之后的代码。但它不会阻止
.map
迭代继续进行回调的下一次调用,因为它不是发生
wait
async
函数的一部分

另一方面,for
循环的
是与发生
await
时相同的
async
函数的一部分,因此迭代仅在等待的承诺解决时继续

如果您希望“并行”执行数据库请求,即在不等待前一个请求解决的情况下启动下一个请求,请使用
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 ... */

原因是,
.map
在不等待的情况下一个接一个地执行回调。
await
完成了它的工作,但这只会延迟
await
之后的代码。但它不会阻止
.map
迭代继续进行回调的下一次调用,因为它不是发生
wait
async
函数的一部分

另一方面,for
循环的
是与发生
await
时相同的
async
函数的一部分,因此迭代仅在等待的承诺解决时继续

如果您希望“并行”执行数据库请求,即在不等待前一个请求解决的情况下启动下一个请求,请使用
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 ... */