点击运算符-为什么一个由其他2个可观察对象扩展的Observable触发2次点击而不是1次?

时间:2018-11-23 13:05:47

标签: javascript reactive-programming rxjs6

通过以下代码:

const parent$ = interval(2000).pipe(
  map(x => 'parent' + x),
  tap(_ => console.log('click$'))
);

const child$ = parent$.pipe(map(x => x + ' from child 1'));
const child2$ = parent$.pipe(map(x => x + ' from child 2'));

child$.subscribe((v) => console.log(v));
child2$.subscribe((v) => console.log(v));

我期望这个输出:

click$
parent0 from child 1
parent0 from child 2
...

正确的输出是:

click$
parent0 from child 1
click$
parent0 from child 2
...

为什么click $ Tap会发出两次?

实施:https://stackblitz.com/edit/rxjs-gpxoud?devtoolsheight=60

2 个答案:

答案 0 :(得分:3)

您获得的输出是因为它贯穿并触发了每个订阅的tap副作用。

为了获得您期望的输出,您需要添加一个shareReplay

const parent$ = interval(2000).pipe(
  map(x => 'parent' + x),
  tap(_ => console.log('click$')),
  shareReplay(1)
);

这样,parent$可观察者的每个订户都“共享” parent$可观察者的发射。然后,Tap仅被调用一次。

您可以在此处以闪电战的形式查看它:

https://stackblitz.com/edit/rxjs-rvymjx

答案 1 :(得分:0)

更好地了解这段代码正在发生的事情

    let i = 0;
    const parent$ = interval(2000).pipe(
        map((x) => `parent ${x} - ${i++}`),
        tap((_) => console.log('click$')),
    );

    const child$ = parent$.pipe(map((x) => x + ' from child 1'));
    const child2$ = parent$.pipe(map((x) => x + ' from child 2'));

    child$.subscribe(console.log);
    child2$.subscribe(console.log);

您看到每次订阅都会触发父级