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

如何合并RxJS marble图表 测试多帧发射的Observable

问题根因

  1. 你自行拼接的marble不符合预期,是因为对marble语法的帧计算规则理解有误:()包裹的所有值属于同一帧,括号本身的字符长度不会占用额外帧位,你之前认为(bcdef)占5帧所以g跑到第9帧,是错误的认知。
  2. 你使用combineLatest报错,是因为该操作符的特性不符合需求:它需要所有输入Observable都至少发射过一次值才会输出,且输出的是所有输入最新值的数组,无法还原你预期的依次独立发射a~g的逻辑。

可行方案

有两种实现方式都可以满足测试需求:

方案1:直接编写正确的单个marble图

按照marble语法规则,你要的发射逻辑对应的单marble写法如下:

'-a(bcdef)g'

对应的帧发射逻辑完全符合你的要求:

  • 帧0:无发射
  • 帧1:发射a
  • 帧2:同步发射b/c/d/e/f
  • 帧3:发射g

对应的测试代码示例:

const values = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7 };
expectObservable(你的被测Observable$).toBe('-a(bcdef)g', values);

如果你之前测试时发现g跑到第9帧,大概率是你的测试代码存在其他错误(比如传入的marble多写了额外的横杠、值映射错误等),可以核对下marble字符串的写法。

方案2:合并多个marble Observable

如果你确实需要拆分多个marble来写,不要用combineLatest,改用merge操作符即可,它会按时间线合并多个Observable的发射,不改变每个值的原始发射时间,完全符合你的需求:

import { merge } from 'rxjs';
import { cold } from 'jasmine-marbles'; // 或你使用的测试库对应的cold方法

const values = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7 };
const expected1$ = cold('-a(bcdef)', values);
const expected2$ = cold('--g', values);

const expected$ = merge(expected1$, expected2$);
expectObservable(你的被测Observable$).toBe(expected$);

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

相关产品推荐
方舟 Agent Plan

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

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