ゼロからオブザーバブルを作成し、オブザーバーエラーが発生して完了した場合、サブスクリプションの完了部分は呼び出されません。
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
エラーが発生したときに完了しないのはなぜですか?
エラーは完了を意味するため、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
私は同じ質問をしていましたが、私はこれにぶつかりました github issue 。
この場合、finally
オブジェクトのObservable
メソッドを使用する必要があるようです。
そのスレッドのAleksandr-Leotechからの引用:
完全なものと最終的にはまったく異なるものです。 Completeは、Steamが正常に終了したことを意味します。あなたは多くの成功の呼び出しを持つことができるからです。最後に、Steamが正常に終了したかどうかを意味します。
HTTPリクエストでは明らかではありませんが、2つの追加シナリオを想像してください。
マウスイベント。成功コールバックの終わりのないSteamを受信しますが、ユーザーイベントは停止しないため(バグコードで例外をトリガーしない限り、エラーが発生し、最終的にエラーが発生します)、最終的にまたは完了することはありません。
Webソケットの使用。複数の成功コールバックを取得しますが、ある時点でバックエンドとの通信が停止し、エラーが発生して最終的にエラーが発生しない限り、完了と最終の両方が取得されます。
そのため、成功呼び出しが複数回またはまったくない、エラー呼び出しが0回または1回、完了が0回または1回、最終的にゼロ回または1回発生する場合があります。
別のおそらく最も簡単な解決策は、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")
);