サブスクライブで最後に観察可能


105

この記事によるonCompleteと、のonError機能subscribeは相互に排他的です。

onErrorまたはのいずれかでonCompleteイベントが発生しsubscribeます。
エラーを受け取ったか、情報のストリームを正常に終了したかに関係なく、実行する必要がある論理ブロックがあります。

私はfinallypythonのようなものを探しましたが、私が見つけたのはfinally、私が作成したオブザーバブルにアタッチする必要があるものだけです。

しかし、私がサブスクライブするとき、およびストリームが正常に終了したか、エラーが発生したかに関係なく、そのロジックを実行したいのです。

何か案は?

回答:


130

この演算子の現在の「pipable」バリアントが呼び出されますfinalize()(RxJS 6以降)。以前の、現在は非推奨の「パッチ」演算子が呼び出されましたfinally()(RxJS 5.5まで)。

finalize()オペレーターは実は正しいと思います。あなたは言う:

私がサブスクライブしたとき、そしてストリームが終了した後にのみ、そのロジックを実行します

これは問題ないと思います。必要に応じて、サブスクライブsourceするfinalize()前にシングルを使用できます。これにより、常に使用する必要がなくなりますfinalize()

let source = new Observable(observer => {
  observer.next(1);
  observer.error('error message');
  observer.next(3);
  observer.complete();
}).pipe(
  publish(),
);

source.pipe(
  finalize(() => console.log('Finally callback')),
).subscribe(
  value => console.log('#1 Next:', value),
  error => console.log('#1 Error:', error),
  () => console.log('#1 Complete')
);

source.subscribe(
  value => console.log('#2 Next:', value),
  error => console.log('#2 Error:', error),
  () => console.log('#2 Complete')
);

source.connect();

これはコンソールに出力されます:

#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message

2019年1月:RxJS 6用に更新


1
これはPromiseの逆のパターンの一種であり、finally()メソッドが最初に追加され、サブスクリプションが強制的にパス/フェイルを強制するという点で興味深いです。
BradGreens 2017年

7
ええ、それはあまりにも悪いです。finallyブロックはコードの最後に来ると考えるでしょう。
d512 2017年

Angular JSのプロミスシステムが気に入りました... d512が「最終的に」は最後になると期待していたので...これはまったく好きではありません...
Sampgun

10
RXJS 5.5以降、「最終的に」は監視可能なメソッドではなくなりました。代わりに "finalize"演算子を使用してください:source.pipe(finalize(()=> console.log( 'Finally callback')))。subscribe(...); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy

finalizeの問題は、 "complete()"呼び出しを待つことです。各放出で最終的に必要な場合(観測可能な放出が成功し場合はaを実行、エラーが発生した場合は代わりにbを実行します。どちらの場合もcを実行します)。
robertotomás

64

私のために働いた唯一のものはこれです

fetchData()
  .subscribe(
    (data) => {
       //Called when success
     },
    (error) => {
       //Called when error
    }
  ).add(() => {
       //Called when operation is complete (both success and error)
  });

26

AngularアプリケーションでRxJS 5.5.7を使用しfinalizeていて、成功またはエラーのコールバックの前に発生するため、演算子の使用は私のユースケースでは奇妙な動作をします。

簡単な例:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000),
    finalize(() => {
      // Do some work after complete...
      console.log('Finalize method executed before "Data available" (or error thrown)');
    })
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );

addサブスクリプションでmedhod を使用して、自分がやりたいことを達成する必要がありました。基本的finallyに、成功またはエラーのコールバックが行われた後のコールバック。同様にtry..catch..finallyブロックまたはPromise.finally方法。

簡単な例:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000)
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );
  .add(() => {
    // Do some work after complete...
    console.log('At this point the success or error callbacks has been completed.');
  });

お役に立ててうれしいです。
pcasme
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.