2017-08-03 123 views
5

總之: 如何在流錯誤後繼續收聽,而不是在每.subscribe之前加上.catch爲什麼Rxjs錯誤地取消訂閱?

如果您需要更多的細節他們在這裏:

讓我們假設我有當前用戶或空的主題。我有時從API獲取數據併發送給主題。它相應地更新視圖。 但是,在某些時候,我的服務器上發生錯誤,我希望我的應用程序繼續像以前一樣工作,但通知某些地方有關該錯誤並保持聆聽我的主題。

最初我以爲如果我只是做userSubject.error(...)它只會觸發.catch回調和error處理器上的訂閱,並跳過所有成功的處理程序和鏈。 如果我打電話userSubject.next(...)後我所有的連鎖店和訂戶將像以前一樣工作

但是不幸的是情況並非如此。在第一個未被捕獲的.error之後,它將訂閱者從流中取消訂閱,並且它們不再運行。

所以我的問題:爲什麼? 如果我想正常處理null值,但是也只能在某些地方處理錯誤,我該怎麼辦?

這裏是鏈接到RxJs源代碼中的錯誤認購退訂 https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts#L140

回答

5

Rx觀測follow the grammarnext*(error|complete)?,這意味着它們可以產生什麼errorcomplete通知已交付之後。

爲什麼這個問題可以從Rx design guidelines找到一個解釋:

單消息,表明可觀察序列已完成,確保可觀察到的序列的消費者可以確定性地證明它是安全的,執行清理操作。

單個故障進一步確保可以爲在多個可觀察序列上工作的操作員維護中止語義。

總之,如果你希望你的觀察員繼續聽受試者已經出現服務器錯誤後,也不能提供該錯誤的問題,而是在一些其他的方式處理它(例如使用catchretry或將錯誤傳遞給專門的主題)。

+0

明白謝謝! – mgrinko

3

每個Observable都會發出零個或多個next通知和一個errorcomplete但從來都不是。

因此,受試者有內部狀態。

然後它取決於你如何構建你的鏈。例如,您可以使用retry()錯誤地重新訂閱其源Observable。

或者當你值傳遞給你的主題,你可以只發送next通知,而忽略其他兩個:

.subscribe(v => subject.next(v)); 

或者,如果你想扔的錯誤當用戶null你可以使用任何運營商,捕捉例外並將它們作爲錯誤通知發送。例如像這樣:

.map(v => { 
    if (v === null) { 
     throw new Error("It's broken"); 
    } 
    return v; 
}) 

無論如何,很難給出更精確的建議,沒有任何代碼。

+0

謝謝你將瞭解什麼是'retry()' – mgrinko