web-dev-qa-db-ja.com

rxjsでチェーンシーケンスを実行する方法

私は次のようなものにしたいと思います:

this._myService.doSomething().subscribe(result => {
  doSomething()
});
.then( () => dosthelse() )
.then( () => dosanotherthing() )

だから私は.thenを約束のように連鎖させたい。 Rxjsでそれを行うにはどうすればよいですか?

this._myService.getLoginScreen().subscribe( result => {
      window.location.href = MyService.LOGIN_URL;
      /// I would like to wait for the site to load and alert something from       the url, when I do it here it alerts the old one
    });
   .then (alert(anotherService.partOfTheUrl())


getLoginScreen() {
  return this.http.get(myService.LOGIN_URL)
.flatMap(result => this.changeBrowserUrl())
.subscribe( result => //i want to do sth when the page is loaded//);
}

changeBrowserUrl(): Observable<any> {
return Observable.create( observer => {
window.location.href = myService.LOGIN_URL;
observer.next();
});
}
36
adam nowak

オブザーバブルのthenと同等の値はflatMapになります。ここでいくつかの使用例を見ることができます:

あなたの例では、次のようなことができます:

this._myService.doSomething()
  .flatMap(function(x){return functionReturningObservableOrPromise(x)})
  .flatMap(...ad infinitum)
  .subscribe(...final processing)

flatMapでobservableをチェーンする場合、PromiseまたはObservableを返す必要があるため、関数が返すもののタイプに注意してください。

59
user3743222

dosthelseまたはdosanotherthingが生の値を返す場合、使用する演算子はmapです。オブザーバブルの場合、演算子はflatMap(または同等)です。

命令的に何かをしたい場合。非同期処理チェーンの外側では、do演算子を活用できます。

dosthelseがobservableを返し、dosanotherthingがrawオブジェクトであると仮定すると、コードは次のようになります。

this._myService.doSomething()
  .do(result => {
    doSomething();
  })
  .flatMap( () => dosthelse() )
  .map( () => dosanotherthing() );

Subcribeメソッドの戻り値を返す場合、それはオブザーバブルではなくサブスクリプションオブジェクトに対応することに注意してください。サブスクリプションオブジェクトは、主にオブザーバブルをキャンセルできるようにするためのものであり、非同期処理チェーンに参加することはできません。

実際、ほとんどの場合、チェーンの最後でサブスクライブします。

だから私はこのようにあなたのコードをリファクタリングします:

this._myService.getLoginScreen().subscribe( result => {
  window.location.href = MyService.LOGIN_URL;
  /// I would like to wait for the site to load and alert something from       the url, when I do it here it alerts the old one
  alert(anotherService.partOfTheUrl()
});

getLoginScreen() {
  return this.http.get(myService.LOGIN_URL)
    .flatMap(result => this.changeBrowserUrl())
    .do( result => //i want to do sth when the page is loaded//);
}

changeBrowserUrl(): Observable<any> {
  return Observable.create( observer => {
    window.location.href = myService.LOGIN_URL;
    observer.next();
  });
}
11