【发布时间】:2019-04-07 01:10:09
【问题描述】:
我正在构建一个应用程序,但我在 for 循环中遇到了问题。
在我的函数中,我得到了两个数组作为参数(payload.data.start 和 payload.data.end),我试图将它推入 mongodb。 我的代码是这样的
async function emplaceAval (state, payload, blockInfo, context) {
for(var i=0 ; i<payload.data.start.length ; i++) // start and end have the same length
{
const user =await User.findOne({ 'account': payload.data.account })
user.availability.push({start: new Date(payload.data.start[i]+'Z') , end: new Date(payload.data.end[i]+'Z')});
await user.save();
}
}
问题是我经常丢失数据。丢失数据是指 i 在 user.save 发生之前发生变化。
我考虑使用 forEach ,但是我有两个数组需要一起保存,所以我不能。
我认为的第二种解决方案是创建一个索引数组。例如,如果我的数组的长度是 5 ,我将创建一个 indexTable=[0 , 1 , 2 , 3 , 4 ] 并且我将使用 asyncForEach 这个数组。但我不认为这种解决方案是可取的。 有任何想法吗?提前致谢
【问题讨论】:
-
await&function (err, user)彼此不兼容,.. IOW:如果您希望 mongoDb 使用 promise,请不要使用回调。例如。试试..const user = await User.findOne({ 'account': payload.data.account }); -
我不使用 mongodb,我希望 save 也是异步的,.. 所以也许可以试试
await user.save();你也可以告诉我们你更新的代码,只是更新你的问题。 -
that the i changes before user.save,查看您修改后的代码,现在不应该发生这种情况。但无论如何我都会将var i更改为let i,这将创建一个块范围的变量,因此即使您的异步操作不同步,我也不会丢失。 -
await仅在函数返回承诺时有效。只是将var更改为let是虚拟解决方案,因为这将解决关闭而不是承诺的问题。阅读更多关于 async-await 和 promise 的内容。还要检查user.save和其他在 for 循环中调用的函数返回什么。 -
你为什么要循环播放?在我看来,这只是一个简单的
$push操作与$each。显示您要更新的数据以及对文档所做的预期更改,您将专注于 Promise,而这不是实际需要解决的问题的一部分。
标签: javascript mongodb for-loop foreach async-await