NGRX Side Effect实现:等待Store数据或取消的方案咨询
实现支持等待Store数据与取消的NGRX Side Effect
嘿,我刚好处理过类似的NGRX场景,咱们一步步来实现这个满足你需求的Side Effect吧!核心就是要让Effect能等待Store里的激活features,同时支持随时取消等待,还要适配features从服务器获取、运行时动态更新的场景。
第一步:定义必要的Actions
先把需要的Action补全,除了你已经有的加载features的Action,还要新增等待、取消等待以及数据就绪的Action:
import { createAction, props } from '@ngrx/store'; import { Feature } from './feature.model'; // 你已有的加载相关Action export const loadFeatures = createAction('[Feature] Load Features'); export const loadFeaturesSuccess = createAction('[Feature] Load Features Success', props<{ features: Feature[] }>()); // 新增的等待与取消Action export const waitForActiveFeatures = createAction('[Feature] Wait for Active Features'); export const cancelWaitForActiveFeatures = createAction('[Feature] Cancel Wait for Active Features'); export const activeFeaturesReady = createAction('[Feature] Active Features Ready', props<{ activeFeatures: Feature[] }>());
第二步:编写核心Side Effect
这是最关键的部分,我们用RxJS的操作符来实现等待和取消逻辑:
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { of } from 'rxjs'; import { filter, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators'; import { AppState } from '../app.state'; import * as FeatureActions from './feature.actions'; import { FeatureService } from './feature.service'; // 你的features请求服务 @Injectable() export class FeatureEffects { // 等待激活features的核心Effect waitForActiveFeatures$ = createEffect(() => this.actions$.pipe( // 监听触发等待的Action ofType(FeatureActions.waitForActiveFeatures), // 实时获取Store中的features数据 withLatestFrom(this.store.select(state => state.features)), // 过滤出存在激活features的情况 filter(([_, features]) => features.some(f => f.activated)), // 触发就绪Action,传递激活的features switchMap(([_, features]) => of(FeatureActions.activeFeaturesReady({ activeFeatures: features.filter(f => f.activated) })) ), // 关键:收到取消Action时立刻终止当前流 takeUntil(this.actions$.pipe(ofType(FeatureActions.cancelWaitForActiveFeatures))) ) ); // 可选:加载features同时支持取消的Effect loadAndWaitForActiveFeatures$ = createEffect(() => this.actions$.pipe( ofType(FeatureActions.loadFeatures), switchMap(() => // 替换成你的HTTP请求获取features逻辑 this.featureService.getFeatures().pipe( switchMap(features => of(FeatureActions.loadFeaturesSuccess({ features }))), // 加载过程中也支持取消 takeUntil(this.actions$.pipe(ofType(FeatureActions.cancelWaitForActiveFeatures))) ) ) ) ); constructor( private actions$: Actions, private store: Store<AppState>, private featureService: FeatureService ) {} }
第三步:组件中使用与取消处理
在依赖激活features的组件里,我们可以触发等待,并在适当时候(比如组件销毁、用户手动操作)取消等待:
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { AppState } from '../app.state'; import * as FeatureActions from './feature.actions'; @Component({ selector: 'app-feature-dependent', templateUrl: './feature-dependent.component.html' }) export class FeatureDependentComponent implements OnInit, OnDestroy { private destroy$ = new Subject<void>(); constructor(private store: Store<AppState>) {} ngOnInit(): void { // 触发等待激活features this.store.dispatch(FeatureActions.waitForActiveFeatures()); // 监听就绪事件,处理业务逻辑 this.store.select(state => state.features) .pipe( filter(features => features.some(f => f.activated)), takeUntil(this.destroy$) ) .subscribe(features => { const activeFeatures = features.filter(f => f.activated); // 这里写你的业务逻辑,比如初始化依赖组件、加载对应资源等 console.log('激活的features已就绪:', activeFeatures); }); } ngOnDestroy(): void { // 组件销毁时,取消等待并清理订阅 this.store.dispatch(FeatureActions.cancelWaitForActiveFeatures()); this.destroy$.next(); this.destroy$.complete(); } // 可选:提供手动取消的方法(比如用户点击取消按钮) onCancelWait(): void { this.store.dispatch(FeatureActions.cancelWaitForActiveFeatures()); } }
关键逻辑说明
- 取消机制:用
takeUntil操作符监听取消Action,一旦触发就终止当前Effect流,不管是等待过程还是正在加载数据,都能立刻停止。 - 等待数据:
withLatestFrom结合filter,持续监听Store中的features,直到满足“存在激活features”的条件才继续执行后续逻辑。 - 内存泄漏防护:组件中用
destroy$Subject配合takeUntil,在组件销毁时清理订阅,同时触发取消Action,避免残留的流占用资源。
这样实现后,不管是应用启动时加载features,还是运行时features动态变更,Effect都能正确等待激活的features,并且随时支持取消操作,完美适配你的场景!
内容的提问来源于stack exchange,提问作者mesx
相关产品推荐
相关产品推荐

