2015-12-04 61 views
8
完成可觀察

比方說,我們有一個可觀察我怎樣才能在RxJS

var observable = Rx.Observable 
    .fromEvent(document.getElementById('emitter'), 'click'); 

我怎樣才能使它完成(將觸發的onComplete事件所有訂閱觀察員)?

回答

13

在這種現在的形式,你不能。您的可觀察數據源自未完成的來源,因此它本身無法完成。你可以做的是擴大這個來源與完成條件。這會工作,如:

var end$ = new Rx.Subject(); 
var observable = Rx.Observable 
    .fromEvent(document.getElementById('emitter'), 'click') 
    .takeUntil(end$); 

當你想結束observable,你做end$.onNext("anything you want here");。結局事件是由你產生的。如果這是產生該事件的另一個源(按鍵等),那麼您可以直接將源自該源的可觀察值作爲參數takeUntil

文檔:

+0

這似乎是潛在的瀏覽器應用程序內存泄漏的危險。似乎可以有無數的觀察者已經從範圍中移除了與HTML元素相關聯的連接。它可能會阻止GC從內存中刪除這些元素以及其他許多文件... – ulfryk

+1

??我不跟着你。這是什麼'?無論如何,所有觀察者都會觸發'onCompleted'處理程序,這就是你所要求的。關於內存泄漏,當最後一個觀察者已經從'fromEvent'創建的observable退訂時,創建的事件偵聽器被刪除。 – user3743222

+0

「什麼會觸發所有訂閱的觀察者的onComplete事件」是我的問題的第二部分。 我需要實現的是刪除事件監聽器。Observable完全完成,所以當我不再聽事件時,我可以刪除所有過時的引用。 – ulfryk

1

什麼工作對我來說是使用take()操作。它會在x次事件後觸發完整的回調。所以通過1,它會在第一個事件之後完成。

打字稿:

private preloadImage(url: string): Observable<Event> { 
    let img = new Image(); 
    let imageSource = Observable.fromEvent(img, "load"); 

    img.src = url; 

    return imageSource.take(1); 
} 
+0

'first()'可以用來代替'take(1)' –

1

我想你正在尋找的是dispose()方法。

來自:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md#cold-vs-hot-observables

注意,訂閱方法返回一個一次性的,這樣就可以退訂序列,輕鬆地進行處理。當您在可觀察序列上調用dispose方法時,觀察者將停止監聽數據的觀測值。通常情況下,除非需要提前退訂,或者源觀察序列的壽命比觀察者長,否則不需要顯式調用處置。 Rx中的訂閱設計用於在不使用終結器的情況下進行即開即用的情況。請注意,Observable運算符的默認行爲是儘快處理訂閱(即發佈onCompleted或onError消息時)。例如,代碼將x訂閱到序列a和b。如果拋出一個錯誤,x將立即退出b。