NgRx模块初始化时Action未触发,添加Timeout后正常的原因排查
NgRx Effects独立API下模块构造函数dispatch Action无效的原因及解决方案
问题原因
模块构造函数的执行时机早于NgRx状态与Effects的完全初始化流程:
- Angular模块构造函数在模块实例化时同步执行,但此时模块providers中通过
provideState和provideEffects注册的NgRx逻辑仍在初始化过程中——reducer尚未完成向Store的注册,Effects的监听机制也未启动。 - 此时直接dispatch的
CreateChatComponent()Action无法被未就绪的NgRx系统捕获处理;而setTimeout会将dispatch逻辑推入宏任务队列,等当前模块初始化的所有同步任务完成、NgRx全量初始化完毕后再执行,因此Action能正常生效。
解决方案
方案1:将初始化Action移至组件生命周期钩子
组件初始化阶段,模块的所有providers已完成注册,此时dispatch Action可被NgRx正常处理:
@Component({ // 组件元数据 }) export class ChatComponent implements OnInit { constructor(private readonly store: Store) {} ngOnInit(): void { this.store.dispatch(CreateChatComponent()); } }
方案2:使用APP_INITIALIZER完成模块级初始化
若需在模块层面执行初始化逻辑,可借助APP_INITIALIZER,它会在应用初始化阶段执行,且等待初始化逻辑完成后再继续应用启动:
import { APP_INITIALIZER } from '@angular/core'; import { Store } from '@ngrx/store'; @NgModule({ providers: [ provideState({ name: 'chat', reducer: chatReducer }), provideEffects(ChatEffects), { provide: APP_INITIALIZER, useFactory: (store: Store) => () => { store.dispatch(CreateChatComponent()); }, deps: [Store], multi: true } ], declarations: [ChatComponent], }) export class ChatModule {}
内容的提问来源于stack exchange,提问作者Marc Fernandez
相关产品推荐
相关产品推荐

