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
相关产品推荐
相关产品推荐

