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

如何用RxJS实现待办列表且无需在操作符中使用外部状态elements

你可以用scan操作符在RxJS流内部维护待办列表状态,完全不需要外部变量,核心思路是把所有触发列表更新的事件流合并,每个事件发射一个状态修改函数,通过scan累积计算最新的列表状态,实现代码如下:

import { merge, interval, scan, mergeMap, map, filter, take } from 'rxjs';

// 原有依赖保持不变
// api.fetchElement: ({ count: number, exclude: string[] }) => Observable<Element[]>
// removedElementId$: Subject<string>

const todoList$ = merge(
  // 初始加载5个条目
  api.fetchElement({ count: 5 }).pipe(
    map(newElements => () => newElements)
  ),
  // 删除单个条目后补全新条目
  removedElementId$.pipe(
    mergeMap(removedId => 
      // 仅拉取1个补位,如需替换全量5个可修改count参数为5,直接返回newElements即可
      api.fetchElement({ count: 1, exclude: [removedId] }).pipe(
        map(newElement => (state: Element[]) => [
          ...state.filter(el => el.id !== removedId),
          ...newElement
        ])
      )
    )
  ),
  // 每3秒检查一次,列表不足5个时自动补全
  interval(3000).pipe(
    mergeMap(() => todoList$.pipe(take(1))),
    filter(state => state.length < 5),
    mergeMap(state => api.fetchElement({
      count: 5 - state.length,
      exclude: state.map(el => el.id)
    }).pipe(
      map(newElements => (state: Element[]) => [...state, ...newElements])
    ))
  )
).pipe(
  // 流内部维护列表状态,无外部依赖
  scan((currentState: Element[], reducer: (state: Element[]) => Element[]) => reducer(currentState), [])
);

// 直接订阅拿到实时列表用于视图渲染即可
todoList$.subscribe(list => {
  // 此处赋值给Angular组件变量即可渲染展示
  console.log('最新待办列表', list);
});

核心逻辑说明

  • 所有状态变更都封装在流内部的reducer函数中,没有任何外部共享状态依赖,完全符合RxJS纯流设计原则
  • 三个触发源(初始加载、删除补全、定时空列表补全)完全解耦,各自独立实现状态修改逻辑,后续迭代需求可单独调整对应模块
  • 最终输出的todoList$是响应式的实时数据流,不需要额外维护中间变量,直接配合Angular的async管道使用更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:48:02