假设我们有一个模型“用户”和一个模型“游戏”。
一个用户可以拥有多个游戏,但一个游戏只属于一个用户。
在“用户”模型中,我们有字段“gamesCount” - 用户拥有的游戏总数
在“游戏”模型中,我们有字段userId - 与用户相关
现在我们需要遍历所有用户,并且对于每个用户,我们查询“游戏”集合以获取用户拥有的游戏数量,然后将值“gamesCount”保存到用户模型。
我有两段代码:
updateUserGamesCount: async function (req, res) {
try {
let users = await User.find({});
for (let user of users) {
user.gamesCount= await Game.count({userId: user._id});
await user.save();
}
return res.status(200).send("Success");
} catch (err) {
res.status(500).send(err);
}
}
此第1段不起作用。它只是加载一段时间然后请求超时。当我尝试修改gamesCount值以查看它是否已更新时,则在第1次代码段运行后,该值不会更新。
updateUserGamesCount: async function (req, res) {
try {
let users = await User.find({});
for (let user of users) {
user.gamesCount= await Game.count({userId: user._id});
user.save();
}
return res.status(200).send("Success");
} catch (err) {
res.status(500).send(err);
}
}
这第二个片段有效。唯一的区别在于第二个片段,我在user.save();
之前删除了await为什么会这样?我认为user.save()是异步的,我们需要使用await?这些代码行的执行顺序究竟是什么?
非常感谢。
答案 0 :(得分:2)
问:为什么第一个代码段工作而不是另一个?
A:我认为我们需要明确“它有效”的定义。它工作,因为没有错误被抛出?
我怀疑您的第二个代码段完全不起作用,而您只是通过删除await
关键字来屏蔽错误。
第一个示例有效,因为您在继续之前等待save
操作完成,如果抛出exception
,则它会被try
块捕获。而第二个代码不再等待save()
响应返回,只是返回success
。
如果这个理论成立,那么任何事都不应该saved
成功。无论是否有效,只有数据库可以说实话。第一个代码片段是正确的方法,但它可以在性能方面做得更好。
考虑捆绑所有save
承诺,并为可能的性能增益做promise.all(...)
。或者,在某些用例中,执行包含所有修改的一个save
操作也是一个不错的选择。
请参阅:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all