为什么Mongoose中find搭配for await使用未生效,邮箱展示异常?
问题原因
- 核心错误是混用了Mongoose的回调语法和
async/await异步语法:当你给Attachment.find()、User.find()传入回调函数时,方法返回的不再是可等待的Promise,你写的await完全不生效,所有数据库查询会异步并发执行,完成顺序不可控,所以会出现邮箱拼错行、字段为空的问题。 for await是用来遍历异步迭代器的语法,你遍历的是普通的附件数组,根本不需要也不适用这个语法,自然解决不了问题。- 具体执行逻辑错位:原来的代码不等用户查询完成,就直接拼接了
</td>进入下一个附件行的拼接,等用户查询的回调异步执行时,html_table已经拼到后面的行,邮箱自然就插到了其他附件的字段里。
修复后的代码
router.get('/', auth, async (req, res) => { try { // 去掉回调,直接await获取附件列表 const attachments = await Attachment.find() let html_table = "" // 普通for of遍历即可,不需要for await for (const attachment of attachments) { html_table += "<tr>" html_table += "<td>" html_table += attachment.file_name html_table += "</td>" html_table += "<td>" // 去掉回调,直接await获取对应当前附件的用户列表 const users = await User.find({ attachments: attachment.id }) for (const user of users){ html_table += user.email + "<br />" } html_table += "</td>" html_table += "</tr>" } res.json(html_table) } catch (e) { res.status(500).json({ message: e.message }) } })
可选优化建议
如果附件数量较多,多次串行查询用户会导致接口响应慢,可以用MongoDB的聚合查询一次性关联查出所有附件对应的用户,减少数据库查询次数。
内容的提问来源于stack exchange,提问作者Vladislav Sokolov
相关产品推荐
相关产品推荐

