的問題是降低到這一行:
subject.unsubscribe((v) => {
console.log(v);
});
Subject
implements ISubscription
;這意味着它有一個unsubscribe
方法和一個closed
屬性。它的implementation of unsubscribe
如下:
unsubscribe() {
this.isStopped = true;
this.closed = true;
this.observers = null;
}
這是有點殘酷。從本質上講,它可以切斷與主題的任何訂閱者的所有通信,而不必取消訂閱。同樣,它不會從可能會被訂閱的任何可觀察的事物中取消訂閱主題本身。 (它也標記爲已關閉/停止的主題,這是您錯誤的原因。)
鑑於它不會執行任何取消訂閱,它應該如何使用尚不清楚。的this test描述:
it('should disallow new subscriber once subject has been disposed',() => {
表明,它可能是某種解酒從RxJS 4 - 其中退訂被稱爲處置。不管它是什麼原因,我都會建議你永遠不要打電話給它。舉例來說,看看這個片斷:
const source = Rx.Observable
.interval(200)
.take(5)
.do(value => console.log(`source: ${value}`));
const subject = new Rx.Subject();
source.subscribe(subject);
const subscription = subject
.switchMap(() => Rx.Observable
.interval(200)
.take(5)
.delay(500))
.subscribe(value => console.log(`subscription: ${value}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
它贊成一個受觀察的源,然後從主題訂閱可觀察到的組成。
如果unsubscribe
被稱爲關於這個問題,一對夫婦的問題變得很明顯:
- 對象的訂閱源不是取消訂閱,當源試圖調用對象的
next
方法的誤差影響;並且
- 對由該主題組成的觀察值的訂閱未被取消訂閱,因此
switchMap
內的interval
可在unsubscribe
調用之後保持發射。
試試看:
const source = Rx.Observable
.interval(200)
.take(5)
.do(value => console.log(`source: ${value}`));
const subject = new Rx.Subject();
source.subscribe(subject);
const subscription = subject
.switchMap(() => Rx.Observable
.interval(200)
.take(5)
.delay(500))
.subscribe(value => console.log(`subscription: ${value}`));
setTimeout(() => {
console.log("subject.unsubscribe()");
subject.unsubscribe();
}, 700);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
的這一切似乎是可取的行爲,因此呼籲在Subject
unsubscribe
是要避免的東西。
相反,在你的代碼段代碼應該取消使用由subscribe
調用返回的Subscription
:
const subscription = subject.subscribe((v) => {
console.log(v);
});
subscription.unsubscribe();
繼寫這個答案,我發現從Ben Lesh的following comment,與適合我的理論認爲它與處理該主題有關:
如果你想讓主體大聲而憤怒地錯誤,當你next
完成後有用,您可以直接調用unsubscribe
對主題實例本身。
[This test](https://github.com/ReactiveX/rxjs/blob/5.4.2/spec/subjects/AsyncSubject-spec.ts#L125-L141)表明它應該表現出你的行爲方式期待它,不是嗎?其他事情還能繼續嗎? – cartant
嗯,謝謝,檢查[這個運動員](https://plnkr.co/edit/wFRWuiyWtsolP5CESdaA?p=preview),沒有其他東西 –
它看起來有點像打字錯誤,對我來說。將'subject.subscribe'調用的結果分配給一個變量(結果是訂閱)並在訂閱上調用'unsubscribe'而不是主題。隨着這種變化,這個龐然大物似乎做到了我所期望的。 – cartant