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

如何无需等待所有Observable完成即可合并数组流 实现Angular销售数据即时展示

解决方案

核心原因是你现在直接merge两个数组流,页面会直接渲染流最新抛出的数组值,手动注入的单元素数组自然会覆盖之前服务端返回的完整列表。要实现增量追加+全量更新的逻辑,用scan操作符维护列表状态即可,不需要修改你现有InjectSale$.next()的调用逻辑。

修改后的代码如下:

// 需提前导入rxjs的map、scan操作符
import { map, scan } from 'rxjs';

// ... 原有其他代码保持不变

get LastSales() : Observable<Sale[]> {
  if (!this.displayLastSales$) {
    const rTimer$ = timer(0, DefaultRefresh);

    this.displayLastSales$ = rTimer$.pipe(
      switchMap(_ => this.getLastSales()),
      // 将服务端返回的全量数组映射为「全量替换状态」的更新函数
      map(serverSales => (prevSales: Sale[]) => serverSales),
      shareReplay(this.CACHE_SIZE),
      takeUntil(this.refresherToggleSales$)
    );
  }

  // 将手动注入的增量数组映射为「追加更新状态」的更新函数
  const injectUpdate$ = this.InjectSale$.pipe(
    map(newSales => (prevSales: Sale[]) => [...prevSales, ...newSales])
  );

  // 合并两种更新函数流,用scan执行函数维护最终列表状态
  return merge(this.displayLastSales$, injectUpdate$).pipe(
    // 初始状态可根据需求调整为空数组或者其他默认值
    scan((currentSales: Sale[], updateFn) => updateFn(currentSales), [])
  );
}

逻辑说明

  • 无需等待任意流完成,任意流有新值抛出时都会立刻计算最新的列表结果返回给模板渲染:
    1. 首次服务端返回数据时,会执行替换函数,把初始空数组替换为服务端返回的完整销售列表
    2. 手动调用InjectSale$.next([newSale])时,会执行追加函数,把新录入的销售记录直接加到现有列表末尾,实现即时展示
    3. 下次定时拉取接口触发时,会用最新的服务端全量数据替换当前列表,保证本地数据和服务端最终一致
  • 如果需要避免手动新增的记录和后续服务端返回的记录重复,可以把追加更新函数改成如下逻辑,按唯一标识去重即可:
    map(newSales => (prevSales: Sale[]) => [
      ...prevSales.filter(s => !newSales.find(n => n.id === s.id)),
      ...newSales
    ])
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:24:03