Tap 运算符 - 为什么由其他 2 个 Observable 扩展的 Observable 触发点击 2 次而不是 1 次?
Tap operator - Why an Observable expanded by other 2 observables trigger tap 2 times instead of 1?
来自以下代码:
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$ 点击发出两次?
实施:https://stackblitz.com/edit/rxjs-gpxoud?devtoolsheight=60
您得到了您所拥有的输出,因为它运行并触发了每个订阅的 tap
副作用。
为了获得预期的输出,您需要添加 shareReplay
const parent$ = interval(2000).pipe(
map(x => 'parent' + x),
tap(_ => console.log('click$')),
shareReplay(1)
);
这样,parent$
observable 的每个订阅者都是 "sharing" 来自 parent$
observable 的发射。那么 Tap 只被调用一次。
您可以在此处的堆栈闪电战中看到它:
为了更好地理解正在发生的事情,这段代码可能会对您有所帮助
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);
您看到每次订阅都会触发父项
来自以下代码:
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$ 点击发出两次?
实施:https://stackblitz.com/edit/rxjs-gpxoud?devtoolsheight=60
您得到了您所拥有的输出,因为它运行并触发了每个订阅的 tap
副作用。
为了获得预期的输出,您需要添加 shareReplay
const parent$ = interval(2000).pipe(
map(x => 'parent' + x),
tap(_ => console.log('click$')),
shareReplay(1)
);
这样,parent$
observable 的每个订阅者都是 "sharing" 来自 parent$
observable 的发射。那么 Tap 只被调用一次。
您可以在此处的堆栈闪电战中看到它:
为了更好地理解正在发生的事情,这段代码可能会对您有所帮助
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);
您看到每次订阅都会触发父项