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

Angular:多RxJS流独立加载器合并视图模型流——错误时保留历史数据

解决方案:保留历史数据并处理错误状态

要解决错误时保留最后加载数据的问题,核心是让每个数据源的流维护自身的状态历史,而不是每次请求都从头生成状态。可以通过scan操作符累积状态,替代原来直接映射状态的方式,这样就能在错误发生时访问到之前的成功数据。

步骤1:定义状态结构

每个数据源的状态需要包含三个核心字段:

  • data: 最后一次成功加载的数据(初始值可设为null或业务默认值)
  • loading: 是否处于加载状态
  • error: 错误信息(null表示无错误)

初始状态示例:

const initialDataState = {
  data: null,
  loading: false,
  error: null
};

步骤2:重构单个数据源的流

使用scan累积状态,结合switchMap触发请求,同时通过动作类型区分加载、成功、错误三种状态:

// 以source1为例
source1$ = clickEvent$.pipe(
  switchMap(() => 
    // 触发请求,同时发出加载、成功/错误动作
    getData(parameters).pipe(
      map(data => ({ type: 'success', payload: data })),
      catchError(error => of({ type: 'error', payload: error })),
      startWith({ type: 'loading' })
    )
  ),
  // 用scan累积状态,每次基于之前的状态更新
  scan((prevState, action) => {
    switch (action.type) {
      case 'loading':
        // 加载中:保持原有数据,标记加载状态,清空错误
        return { ...prevState, loading: true, error: null };
      case 'success':
        // 成功:更新数据,结束加载,清空错误
        return { data: action.payload, loading: false, error: null };
      case 'error':
        // 错误:保留原有数据,结束加载,记录错误
        return { ...prevState, loading: false, error: action.payload };
      default:
        return prevState;
    }
  }, initialDataState)
);

步骤3:合并流并处理弹窗逻辑

继续用combineLatest合并所有数据源的流,传递给子组件:

dashboardViewModel$ = combineLatest({
  data1: source1$,
  data2: source2$,
  // 其他数据源...
});

子组件中可以通过监听error字段的变化来触发弹窗(比如用distinctUntilChanged过滤重复错误):

// 子组件内监听error
this.dataState$.pipe(
  map(state => state.error),
  distinctUntilChanged(),
  filter(error => error !== null)
).subscribe(error => {
  // 弹出错误弹窗逻辑
  showErrorModal(error);
});

关键优势

  • 每个数据源独立维护自身状态,错误时自动保留最后成功数据
  • 状态更新逻辑清晰,通过动作类型区分不同场景
  • 加载状态、错误状态、数据展示完全解耦,便于维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:12:41