以下是反应式代码(RxJs)的简短代码段
let subj = new Rx.Subject();
let chain = subj
.switchMap(v => Rx.Observable.of(10*v).do(vv => console.log("Switch map", vv)))
.share()
.take(1);
function subscribe(){
chain.subscribe(v => console.log("Next", v),
err => console.log("Error",err),
() => console.log("Completed"));
chain.subscribe(v => console.log("Next2", v),
err => console.log("Error2",err),
() => console.log("Completed2"));
subj.next(Math.random());
}
subscribe();
subscribe();
subscribe();
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
根据documentation链是一个Observable,它应该打印发射的值* 10(switchMap),而只打印一次,无论订阅数量是多少(share),都只对第一个发射的值进行操作,然后完成.
前两个项目符号工作正常,但最后一个无效.
这是我得到的输出:
Switch map 9.022491050934722
Next 9.022491050934722
Completed
Next2 9.022491050934722
Completed2
Switch map 9.172999425126836
Next 9.172999425126836
Completed
Next2 9.172999425126836
Completed2
Switch map 6.168790337405257
Next 6.168790337405257
Completed
Next2 6.168790337405257
Completed2
如您所见,链条已多次完成.
什么使多次完成相同的Observable成为可能?
解决方法:
share是发布和refCount组合的快捷方式,这意味着只要至少有1个订阅者,流就只是“热”,因此,在流完成后,所有活动的订阅者都将自动退订,从而重置流,因为那时有0个订阅者.另外:由于以下任何操作都会影响热状态,因此应将take(1)放在共享前面.
如何使流“真正”共享/热流,与任何订阅者无关:使用发布并连接流:
let subj = new Rx.Subject();
let chain = subj
.switchMap(v => Rx.Observable.of(10*v).do(vv => console.log("Switch map", vv)))
.take(1)
.publish();
chain.connect();
function subscribe(){
chain.subscribe(v => console.log("Next", v),
err => console.log("Error",err),
() => console.log("Completed"));
chain.subscribe(v => console.log("Next2", v),
err => console.log("Error2",err),
() => console.log("Completed2"));
subj.next(Math.random());
}
subscribe();
subscribe();
subscribe();
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>