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

NestJS中Event Emitter监听函数被调用两次的问题排查

问题原因解析

第一种配置出现两次日志的核心原因是创建了两个EmitterService实例,且它们都向同一个EventEmitter2注册了事件监听器。

具体分析:

  1. 第一种配置(TestModule直接声明EmitterService为provider)

    • 假设你的应用根模块(AppModule)已经导入了EmitterModule,那么EmitterModule会创建一个EmitterService实例(记为实例A),并通过@OnEvent装饰器将listentToEvent方法注册到全局唯一的EventEmitter2实例上。
    • 同时,TestModule在自己的providers数组中声明了EmitterService,这会让NestJS为TestModule单独创建另一个EmitterService实例(记为实例B),该实例同样会把listentToEvent方法注册到同一个EventEmitter2上。
    • 当你调用testEventEmitter接口时,使用的是实例B的emitEvent方法,触发msg.sent事件后,EventEmitter2会通知所有已注册的监听器——也就是实例A和实例B的listentToEvent方法都会执行,因此日志会输出两次"second"。
  2. 第二种配置(TestModule导入EmitterModule)

    • TestModule通过导入EmitterModule,共享了EmitterModule导出的EmitterService单例实例(只有实例A)。
    • 此时整个应用中只有一个EmitterService实例,它的listentToEvent方法只会注册一次,因此事件触发后只会输出一次"second"。

总结:

NestJS中,若在多个模块的providers数组中重复声明同一个服务,会为每个模块创建独立的服务实例。而通过导入共享模块(如EmitterModule)的方式,才能保证服务是单例的,避免重复注册监听器这类问题。

内容的提问来源于stack exchange,提问作者Đoàn Đức Bảo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:01:22