Javascript 对于循环和映射差异
我有两个案例,我试图了解发生了什么,但我仍然不清楚,所以我读到,如果我想运行异步调用for loop或map,我需要使用Promise.all 但让我和大家分享一下发生的事情 首先,我使用map更新数据库中的许多记录,它更新了一些而不是所有的数据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
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 ... */