簡體   English   中英

RxJS - 發生錯誤時 observable 不會完成

[英]RxJS - observable doesn't complete when an error occurs

當我從頭開始創建一個 observable 並且有觀察者錯誤,然后完成時,訂閱的完成部分永遠不會被調用。

var observer = Rx.Observable.create(function(observer){
    observer.onError(new Error('no!'));
    observer.onCompleted();
})

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)

輸出是:

errored with Error: no!

我希望它是:

errored with Error: no!
completed

如果我更改代碼以調用 onNext 而不是 onError,則 observable 會正確完成:

var observer = Rx.Observable.create(function(observer){
    observer.onNext('Hi!');
    observer.onCompleted();
})

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)

我得到預期的輸出:

succeeded with Hi! 
completed

為什么發生錯誤時它沒有完成?

這是因為錯誤意味着完成,因此與onCompleted關聯的回調永遠不會被調用。 您可以在此處查看可觀察的 Rxjs 合同( http://reactivex.io/documentation/contract.html ):

Observable 可能會發出零個或多個 OnNext 通知,每個通知代表一個發出的項目,然后它可以通過 OnCompleted 或 OnError 通知跟隨這些發出通知,但不能同時發出這兩個通知。 在發出 OnCompleted 或 OnError 通知后,它可能不會發出任何進一步的通知。`

對於錯誤管理,您可以查看: https : //github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md

另一個可能是最簡單的解決方案可能是使用add()函數。
無論是否發生錯誤,該語句都將始終執行(就像大多數編程語言中的finally語句)。

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)
.add(() => {
    console.log("Will be executed on both success or error of the previous subscription")
);

當我有同樣的問題時,我遇到了這個github issue

顯然在這種情況下finally需要使用Observable對象的方法。

從該線程中引用 Aleksandr-Leotech:

Complete 和 finally 是完全不同的東西。 Complete 表示可觀察到的蒸汽已成功完成。 因為你可以有很多成功的電話。 最后意味着蒸汽已經結束,無論成功與否。

HTTP 請求並不明顯,但可以想象另外兩個場景。

  1. 鼠標事件。 您將收到永無止境的成功回調流,但您永遠不會收到 finally 或 complete,因為用戶事件永遠不會停止(除非您使用錯誤代碼觸發異常,否則您將收到錯誤並最終)。

  2. 使用網絡套接字。 您將獲得多個成功回調,但在某個時間點,您與后端的通信將停止,除非您有一些錯誤,否則您將獲得 complete 和 finally,這將調用 error 和 finally。

因此,您可能會收到多個成功調用或沒有成功調用、零個或一個錯誤調用、零個或一個完整調用以及零個或一個最終調用。

要在 observable 完成或出錯時運行回調,您應該使用 finalize。

前任:

this.service.yourObservable
            .pipe(
               finalize(() => {
                 // * This will always run when observable finishes the stream
                 console.log("Finally!");
                 // * callback for finally
                })  
             ).subscribe(
              {
               next: () => { // * Callback for success },
               error: () => { // * Callback for error },
               complete: () => {// * This gets called only on success }
              })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM