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

NGRX Effect如何监听除指定轮询Action外的所有Action实现会话超时控制

实现方案

核心逻辑采用反向标记排除的思路,不需要正向枚举所有需要触发超时重置的Action,仅需给不需要重置会话计时器的轮询类Action添加统一标识,在Effect中过滤掉带该标识的Action即可适配大规模应用的需求。

步骤1:定义统一的排除标记

给所有不需要重置超时计时器的轮询Action添加skipSessionTimeoutReset标记,支持两种常用的Action定义方式:

  • 函数式Action(NGRX v8+ 推荐用法):在createAction的第三个参数中添加元数据标记
// 轮询类Action定义示例
export const pollCounterUpdate = createAction(
  '[Counter] Poll Update',
  props<{ count: number }>(),
  // 添加排除标记
  { meta: { skipSessionTimeoutReset: true } }
);
  • 类式Action:在Action类上添加静态属性标记
export class PollCounterUpdate implements Action {
  readonly type = '[Counter] Poll Update';
  // 添加排除标记
  static skipSessionTimeoutReset = true;
  constructor(public payload: { count: number }) {}
}

步骤2:修改Effect过滤逻辑

调整原Effect的代码,先过滤掉带排除标记的Action,仅剩余的Action会触发超时计时器重置:

@Injectable()
export class ApplicationEffects {
  APPLICATION_TIMEOUT_TIME = 1000 * 5;

  @Effect()
  extendApplicationTimeout$ = createEffect(() => this.actions$
    .pipe(
      // 过滤掉带排除标记的Action,以下为函数式Action的过滤逻辑
      filter((action: Action & { meta?: { skipSessionTimeoutReset?: boolean } }) => 
        !action.meta?.skipSessionTimeoutReset
      ),
      // 类式Action请替换为以下过滤逻辑
      // filter((action: Action) => !(action.constructor as any).skipSessionTimeoutReset),
      switchMap(() => timer(this.APPLICATION_TIMEOUT_TIME)),
      map(() => new ApplicationActions.LogOut())
    )
  );

  constructor(private actions$: Actions) {}
}

方案优势

  • 维护成本极低:新增需要排除的Action仅需添加对应标记,无需修改Effect代码,完全适配大规模应用场景
  • 逻辑无侵入:标记完全可选,不会影响其他普通Action的会话超时逻辑
  • 扩展性强:后续其他非用户交互类Action(如自动数据同步、后台状态更新等)需要排除时,直接加标记即可生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:27:01