RxJs Observable多次完成

时间:2017-01-29 12:03:51

标签: javascript rxjs observable rxjs5 reactivex

以下是反应代码(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>
&#13;
&#13;
&#13;

根据documentation chain是一个Observable,它应该打印出的值* 10(switchMap),而打印只需一次,无论什么&#39 ; s它拥有的订阅数量(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

如您所见,chain已多次完成 是什么原因可以多次完成相同的Observable次?

1 个答案:

答案 0 :(得分:4)

sharepublishrefCount组合的快捷方式,这意味着只要有至少1个订阅者,流只是“热门”,所以流完成后,所有活动的订户都会自动取消订阅,从而重置流,因为有0个订阅者。另外:您应该将take(1)放在share之前,因为以下任何操作都会影响热状态。

如何使流“真实地”共享/热,不受任何订阅者的限制:使用publishconnect流:

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>