web-dev-qa-db-ja.com

RxJS-エラーが発生した場合、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

OnErrorではなくonNextを呼び出すようにコードを変更すると、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

エラーが発生したときに完了しないのはなぜですか?

39
Oved D

エラーは完了を意味するため、onCompletedに関連付けられたコールバックは呼び出されません。こちらでオブザーバブルのRxjsコントラクトを確認できます( http://reactivex.io/documentation/contract.html ):

Observableは0個以上のOnNext通知を作成でき、それぞれが単一の発行済みアイテムを表し、その後、両方ではなくOnCompleted通知またはOnError通知のいずれかによってそれらの発行通知に続く場合があります。 OnCompletedまたはOnError通知を発行すると、その後、それ以上通知を発行することはできません。

エラー管理については、以下をご覧ください: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md

44
user3743222

私は同じ質問をしていましたが、私はこれにぶつかりました github issue

この場合、finallyオブジェクトのObservableメソッドを使用する必要があるようです。

そのスレッドのAleksandr-Leotechからの引用:

完全なものと最終的にはまったく異なるものです。 Completeは、Steamが正常に終了したことを意味します。あなたは多くの成功の呼び出しを持つことができるからです。最後に、Steamが正常に終了したかどうかを意味します。

HTTPリクエストでは明らかではありませんが、2つの追加シナリオを想像してください。

  1. マウスイベント。成功コールバックの終わりのないSteamを受信しますが、ユーザーイベントは停止しないため(バグコードで例外をトリガーしない限り、エラーが発生し、最終的にエラーが発生します)、最終的にまたは完了することはありません。

  2. Webソケットの使用。複数の成功コールバックを取得しますが、ある時点でバックエンドとの通信が停止し、エラーが発生して最終的にエラーが発生しない限り、完了と最終の両方が取得されます。

そのため、成功呼び出しが複数回またはまったくない、エラー呼び出しが0回または1回、完了が0回または1回、最終的にゼロ回または1回発生する場合があります。

14
coni2k

別のおそらく最も簡単な解決策は、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")
);
3
Just Shadow