Async/Await搭配Mongoose执行异常:API偶现未返回数据问题求助
问题分析与解决方案:Mongoose结合async/await时异步执行顺序异常
你遇到的这个问题核心原因很明确:你给Url.find()传了回调函数,导致它不会返回Promise,所以await根本没起到等待异步操作完成的作用。
为什么会出现日志顺序颠倒?
Mongoose的查询方法有两种使用逻辑:
- 传回调函数:方法会立即执行,查询结果通过回调函数返回,此时方法不会返回Promise对象
- 不传回调:方法会直接返回一个Promise对象,这时候才能配合
await实现等待异步操作完成的效果
你原来的代码里,await Url.find(..., callback)其实是在等待一个非Promise值(因为传了回调,find返回的是查询实例而非Promise),所以await会直接跳过等待,立刻执行后面的console.log("Await called")和响应返回逻辑。而回调函数是在数据库查询真正完成后才触发的,所以URL数据的日志会出现在"Await called"之后,同时因为urlsArray是在回调里填充的,返回响应时它还是空数组,自然拿不到想要的数据。
修正后的代码写法
直接去掉回调,使用Mongoose原生支持的Promise风格调用配合await:
exports.GetAllUrls = async function(req, res, next){ try { // 直接await查询结果,find本身就会返回数组,无需手动遍历push const urls = await Url.find({uid: req.params.uid}); console.log(urls); console.log("Await called"); return res.status(200).json({reply: urls}); } catch(err) { console.log(err); // 记得把错误传递给Express的错误处理中间件,避免请求挂起 next(err); } };
额外提醒
Url.find()的返回值本身就是符合需求的数组,不需要手动遍历再push到新数组,直接使用即可- 一定要在
catch块里调用next(err),让Express的错误处理中间件捕获并处理异常,避免请求一直处于挂起状态 - 后续使用async/await时,要确保
await后面跟着的是Promise对象,现代ORM和数据库驱动基本都支持Promise风格调用,优先用这种方式,避免回调和async/await混用导致逻辑混乱
内容的提问来源于stack exchange,提问作者kaminsky59
相关产品推荐
相关产品推荐

