为何Mongoose中find().exec()返回audiences而非空数组?
为啥这段代码返回的是查询到的
audiences,不是你想要的空数组? 嘿,这问题其实是典型的异步回调和Promise混用踩的坑,咱们掰开揉碎了说:
核心矛盾:exec()的两种用法不能乱混
Mongoose的exec()有两种完全不同的使用姿势:
- Promise模式:不传回调时,它会返回一个Promise,你可以用
.then()/await来处理结果。 - 回调模式:传回调的话,它会直接执行这个回调,不会返回Promise,而且回调里的返回值(比如你写的
return Promise.resolve([]))根本没人管——因为这个回调是异步触发的,外层函数早把exec()的返回值扔出去了。
先看你的代码:
return Audience.find().exec((err, audiences) => { if (err) return errorHandler.handle('audienceService', err); return Promise.resolve([]); });
第一个坑:回调里的return Promise.resolve([])等于白写
当你给exec()传了回调,Mongoose只会在查询完成后把结果audiences塞给回调,至于你在回调里return什么,它完全不关心。你写的return Promise.resolve([])只是从这个回调函数里返回了一个Promise,但这个Promise没有被任何代码接收或者处理,自然没法改变外层函数的返回值。
第二个坑:你误以为外层return的是回调的结果
外层的return语句返回的是Audience.find().exec(...)的结果,而不是回调里的返回值。更关键的是:Mongoose的Query对象(也就是Audience.find()返回的东西)是thenable的——哪怕你用了回调模式,如果你把它当作Promise来用(比如外层函数是async的,或者被其他Promise链调用),它最终还是会resolve为查询到的audiences。这就是为啥你最终拿到的是数据库里的结果,不是你想要的空数组。
想返回空数组?得这么写
如果你就是要忽略查询结果,返回空数组,得用纯Promise模式,别碰回调:
写法1:链式Promise
return Audience.find().exec() .catch(err => { errorHandler.handle('audienceService', err); throw err; // 或者根据你的错误处理逻辑调整 }) .then(() => { return []; // 直接返回空数组就行,不用Promise.resolve });
写法2:async/await(更清爽)
async function fetchAudiences() { try { // 执行查询但不用结果 await Audience.find().exec(); return []; } catch (err) { errorHandler.handle('audienceService', err); throw err; } }
这样就能确保函数返回的是空数组啦~
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

