繁体   English   中英

RxJS combineLatest 每个路径只发射一次

[英]RxJS combineLatest emit only once per path

有没有什么方法/模式可以使用combineLatest()或其他一些运算符,这样如果组合的可观察对象相互依赖,它们只会为 DAG 中具有相同来源的每组路径只发射一次? 我认为用图表解释可能更容易。

图表:

   A C
  /| |
 B | |
  \|/
   D

这里 B 订阅了 A,D 订阅了 A、B 和 C。默认行为是如果 A 发射,D 发射两次:一次是 A 发射,一次是 B 发射(作为 A 发射的结果). 我希望它只发射一次,在两者都发射之后。 但是,如果 C 发射,那么 D 也应该立即发射。

这是代码:

const A = new Rx.BehaviorSubject(1);
const B = A.pipe(Rx.map((x) => x + 1));
const C = new Rx.BehaviorSubject(3);

const D = Rx.combineLatest({ A, B, C });

D.subscribe(console.log); // {A: 1, B: 2, C: 3}
A.next(2); // Two emissions: {A: 2, B: 2, C: 3}, {A: 2, B: 3, C: 3} 
// Would like the second one ONLY, i.e. {A: 2, B: 3, C: 3}
C.next(4); // Correctly emits: {A: 2, B: 3, C: 4}

我尝试过的一种解决方案是将其线性化并使 A、B 和 C 的整个集合成为可观察的:

 {A, C}
    |
{A, C, B}
    |
   {D}

这行得通,但我想知道是否有更好的方法。

如果我理解正确的问题,您希望最终的 Observable D随时发出AB的上游)或C发出,但是,如果A发出,您还需要B发出的值。

如果是这种情况,我将确保任何时候B发出,它不仅发出B的值,还发出其上游A通知的值,然后我将仅传递给combineLatest BC ,就像这样

const A = new BehaviorSubject(1);
const B = A.pipe(map((x) => [x, x + 1]));
const C = new BehaviorSubject(3);

const D = combineLatest({ B, C }).pipe(
  map((val) => ({ A: val.B[0], B: val.B[1], C: val.C }))
);

您可以将zip A、B 放在一起,因此对于每一对发射,您只能在 D 中得到一个。将其与 C 结合起来,这只是一个:

const A = new BehaviorSubject(1);
const B = A.pipe(map((x) => [x, x + 1]));
const C = new BehaviorSubject(3);


const D = combineLatest({ zip(A,B), C })

这需要 A 和 B 都发出一个值,但是因为它们相互依赖,所以在您的示例中这不是问题。

https://www.learnrxjs.io/learn-rxjs/operators/combination/zip

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM