我不明白为什么rxjs共享运算符不能与setTimeout()
一起使用。
我正在尝试了解此blogpost。在此示例中,“共享订阅”的概念似乎没有按预期工作。
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.
答案 0 :(得分:4)
这是预期的输出。
摘自share()运算符上的官方文档:
返回一个新的Observable,它多播(共享)原始Observable。只要有至少一个订户,该Observable便会被预订并发出数据。
这意味着观察者一订阅,可观察对象就开始发射数据。
因此,当第一个订阅语句observable1.subscribe(x => console.log(x));
执行时,观察者将进行订阅,并且observer.next('I am alive.);
语句会发出数据。
当第二个订阅语句执行时,另一个观察者进行订阅,并且它仅接收从该时间点发出的数据。这是observer.next('I am alive again.');
用setTimeout()
方法发出的数据。
我们可以在此StackBlitz demo中清楚地看到这一点,在其中记录Observer1
和Observer2
文本以及接收到的数据。
我认为混淆点在于看到两个I am alive again.
语句。 它被记录了两次,因为我们正在每个订户中对其进行记录。将这些日志语句移至可观察的位置,它们将仅记录一次。这使得可观察对象只执行一次。
答案 1 :(得分:1)
这是share()的假定行为。它仅监视和共享一个动作。这是一个来自learningrxjs.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));