[英]Why does the rxjs share operator not work as expected in this setTimeout() example?
我不明白为什么 rxjs 共享运算符不适用于setTimeout()
。
我试图理解这篇博文。 在此示例中,“共享订阅”的概念似乎没有按预期工作。
const observable1 = Observable.create(observer => {
observer.next(`I am alive.`);
setTimeout(() => {
observer.next(`I am alive again.`);
}, 1000);
}).pipe(share());
observable1.subscribe(x => console.log(x));
observable1.subscribe(x => console.log(x));
预期的:
I am alive.
I am alive again.
实际的:
I am alive.
I am alive again.
I am alive again.
那就是预期的 output。
来自share()运算符的官方文档:
返回一个多播(共享)原始 Observable 的新 Observable。 只要至少有一个订阅者,这个 Observable 就会被订阅并发送数据。
这意味着一旦观察者订阅,observable 就会开始发送数据。
所以当第一个订阅语句observable1.subscribe(x => console.log(x));
执行时,观察者订阅并由observer.next('I am alive.);
陈述。
当第二个订阅语句执行时,另一个观察者订阅并且它只接收从那个时间点发出的数据。 这是observer.next('I am alive again.');
在setTimeout()
方法中。
我们可以在StackBlitz 演示中清楚地看到这一点,我们在其中记录Observer1
和Observer2
文本以及接收到的数据。
我认为混乱的点是看到两个I am alive again.
陈述。 它被记录了两次,因为我们在每个订阅者中都记录了它。 将这些日志语句移动到 observable 中,它们只会被记录一次。 这使得 observable 只执行一次变得更加明显。
这是 share() 的假定行为。 它仅监视和共享一项操作。 这是取自 learnrxjs.com 的示例。 正如你所看到的,只有 tap() 操作符被监控。 mapTo() 运算符被忽略。
// RxJS v6+
import { timer } from 'rxjs';
import { tap, mapTo, share } from 'rxjs/operators';
//emit value in 1s
const source = timer(1000);
//log side effect, emit result
const example = source.pipe(
tap(() => console.log('***SIDE EFFECT***')),
mapTo('***RESULT***')
);
/*
***NOT SHARED, SIDE EFFECT WILL BE EXECUTED
TWICE***
output:
"***SIDE EFFECT***"
"***RESULT***"
"***SIDE EFFECT***"
"***RESULT***"
*/
const subscribe = example.subscribe(val => console.log(val));
const subscribeTwo = example.subscribe(val => console.log(val));
//share observable among subscribers
const sharedExample = example.pipe(share());
/*
***SHARED, SIDE EFFECT EXECUTED ONCE***
output:
"***SIDE EFFECT***"
"***RESULT***"
"***RESULT***"
*/
const subscribeThree = sharedExample.subscribe(val => console.log(val));
const subscribeFour = sharedExample.subscribe(val => console.log(val));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.