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

无触发源Observable时,如何用switchMap取消NGXS中的HTTP请求?

解决方案

方法一:利用NGXS内置的Action配置(推荐)

NGXS原生支持取消未完成的同类型Action,只需在定义Fetch Action时添加cancelUncompleted: true配置,就能自动取消之前未完成的Action实例,进而中止对应的HTTP请求(Angular的HttpClient请求会在订阅取消时自动终止)。

修改后的Store Action代码:

@Action(Fetch, { cancelUncompleted: true })
private fetchFromDatabase(ctx: StateContext<StateModel>) {
  // 移除手动调用的.subscribe(),将Observable返回给NGXS,由框架管理订阅生命周期
  return this.http.get('url').pipe(
    catchError(err => {
      ctx.dispatch(new FetchError());
      return of(false);
    }),
    tap(data => {
      if(typeof data !== 'boolean') {
        ctx.dispatch(new FetchSuccess());
      }
    })
  );
}

方法二:手动维护触发流(自定义场景适用)

如果需要更灵活的逻辑控制,可以在State类中通过Subject追踪Fetch Action的触发事件,结合switchMap实现请求切换:

import { Subject, switchMap, catchError, tap, of } from 'rxjs';
import { State, Action, StateContext, Store } from '@ngxs/store';
import { HttpClient } from '@angular/common/http';

@State<StateModel>({ name: 'yourState' })
export class YourState {
  // 创建Subject用于触发请求流
  private fetchTrigger$ = new Subject<void>();

  constructor(
    private http: HttpClient,
    private store: Store
  ) {
    // 初始化请求处理流
    this.initFetchStream();
  }

  private initFetchStream(): void {
    this.fetchTrigger$.pipe(
      // 新触发时自动取消前一个未完成的请求
      switchMap(() => this.http.get('url').pipe(
        catchError(err => {
          this.store.dispatch(new FetchError());
          return of(false);
        }),
        tap(data => {
          if(typeof data !== 'boolean') {
            this.store.dispatch(new FetchSuccess());
          }
        })
      ))
    ).subscribe();
  }

  @Action(Fetch)
  private fetchFromDatabase(ctx: StateContext<StateModel>): void {
    // 每次分发Fetch Action时,推送信号触发新请求
    this.fetchTrigger$.next();
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:15:40