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

未使用await的异步函数异常:NestJS+Mongoose查询未执行问题

为什么未await的Mongoose updateMany在NestJS中不执行?

问题描述

我正在开发基于NestJS的Web应用,使用Mongoose作为数据库交互模块。在某接口中执行两个异步数据库查询,但未对其使用await。我的预期是:返回this.roleModel.findByIdAndDelete(id)的Promise,同时this.realmModel.updateMany({}, { $pull: { roles: new Types.ObjectId(id) } })会自行完成解析。

示例代码:

removeRole(id: string | Types.ObjectId) {
  this.realmModel.updateMany({}, { $pull: { roles: new Types.ObjectId(id) } });
  return this.roleModel.findByIdAndDelete(id);
}

实际结果却是:返回的Promise已解析,但this.realmModel.updateMany(...)并未执行。若将removeRole声明为async函数,结果符合预期,但我并不关心updateMany的完成时机。我想知道这是NestJS特有的问题,还是JavaScript原生行为?

解答

这不是NestJS特有的问题,属于JavaScript/Node.js的原生行为,核心原因和事件循环、Promise调度以及进程退出时机直接相关:

  • 当你调用this.realmModel.updateMany()时,它会返回一个Promise,但因为你既没有用await等待它完成,也没有对这个Promise做任何后续处理(比如绑定.catch()捕获错误),Node.js的事件循环可能在这个异步数据库请求被调度执行前,就因为当前同步代码执行完毕、没有其他挂起的任务而提前终止。尤其是在HTTP请求处理结束后,如果没有未解决的Promise或其他异步任务,Node.js进程会快速退出,导致updateMany的数据库操作被中断,根本没机会执行。

  • 当把removeRole声明为async函数后,即使你没有await updateMany,async函数本身会返回一个Promise。这个Promise会让Node.js保持事件循环运行,直到函数内部所有同步代码执行完毕,给updateMany足够的时间完成数据库请求,所以操作能正常执行。

  • 补充:Mongoose内部的部分异步操作,在没有被await或监听其Promise状态的情况下,可能会因为内部的懒加载逻辑或未处理Promise拒绝的抑制机制,导致操作没有被真正触发,但这只是次要因素,核心还是Node.js事件循环的退出时机问题。

建议方案

即使你不关心updateMany的执行结果,也应该至少处理它的Promise,避免未处理的错误和操作被中断。比如用catch捕获错误:

removeRole(id: string | Types.ObjectId) {
  this.realmModel.updateMany({}, { $pull: { roles: new Types.ObjectId(id) } })
    .catch(err => console.error('更新Realm角色关联失败:', err));
  return this.roleModel.findByIdAndDelete(id);
}

如果是NestJS项目,推荐使用框架自带的Logger模块来记录错误,更符合项目规范。

内容的提问来源于stack exchange,提问作者Andy95

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:31:04