You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:39:19