2017-05-16 25 views
1

私は観測上の最適化問題を持っている:rxjs/angular4観測可能な最適化

私はユーザー名とパスワードを受け入れる2つのコントロールを持っています。パスワードフィールドの値が変更されると(デバウンスを使用して)、クエリ結果を観測可能な状態に戻すサービスメソッドを呼び出し、その値でモデルを埋めます。

返されたオブザーバブルは、サービスエラーの場合に例外をスローします。しかし、私はそのような場合に空の配列でモデルを塗りつぶしたいだけです。

私の元の実装:

this.passwordControl.valueChanges 
    .debounceTime(500) 
    .filter(_ => this.usernameControl.valid && !this.usernameControl.pristine) 
    .map((password) => new RequestAuthentication(this.usernameControl.value, password)) 
    .mergeMap(auth => this.orgService.getOrganizations(auth)) 
    .catch(_ => { 
     return Observable.of([]); 
    }) 
    .subscribe(orgs => { 
     this.organizations = orgs; 
    }); 

欠点がキャッチ機能が実行されたとき、私はストリームを完了し、私は変化にもう聞くことができない有限の観測可能を返すということです。

私のソリューションは、次のような巣の観測にある:

this.passwordControl.valueChanges 
    .debounceTime(500) 
    .filter(_ => this.usernameControl.valid && !this.usernameControl.pristine) 
    .map((password) => new RequestAuthentication(this.usernameControl.value, password)) 
    .subscribe(auth => { 
    this.orgService.getOrganizations(auth) 
     .catch(_ => Observable.of([])) 
     .subscribe(orgs => { 
     this.organizations = orgs; 
     }); 
    }); 

しかし、これは非常に反応思えません...どのように私はこれらのネストされた観測を避けるため、クリーンなコードを維持するために行う必要がありますか?

+0

なぜあなたは 'orgService.getOrganizations'代わりで例外をキャッチしませんか?この方法では、最初のスニペットフローを破ることはありません – bviale

+0

rxjsの再試行/キャッシュされた値のフォールバックを試してみました。 https://github.com/ipassynk/angular2-learning/blob/master/src/app/http-rxjs/http-rxjs.component.ts –

答えて

0

subscribe()を別のsubscribe()に電話するのはお勧めできません。なぜなら「コールバック地獄」と「購読地獄」を交換するだけだからです。また、あなたは親観察可能鎖からerrorcompleteシグナルを失っています。それにもかかわらず、あなたはいつもそれを避けることができます。

エラーが発生したときにチェーンを終了しない場合は、いくつかの演算子が役立ちます。具体的には:retry()retryWhen()(またonErrorResumeNext())とおそらくもっと。エラー信号がretry()代わりのcatch()使用が発生した場合、あなたが何かをしたくない場合は

:あなたはまだいくつかの副作用を実行できるようにしたい場合は

.mergeMap(...) 
.retry() 
.subscribe(orgs => { 
    this.organizations = orgs; 
}); 

を(ユーザーまたは任意に通知) retry().do()を使用します。

.mergeMap(...) 
.do(null, e => ...) 
.retry() 
.subscribe(orgs => { 
    this.organizations = orgs; 
}); 
+0

をもう一度試すことはできませんが、別のリクエストがトリガーされますが、同じ引数(それは無効です)? – joel

+0

'retry()'演算子は、Observableソースに再登録するだけです。それはあなた次第です。たとえば、Observable.defer()を使用して、いくつかの条件に基づいてObservableの異なるソースを作成したり、同じ理由でObservable.createを使用することができます。 – martin

+0

それは再試行で動作しますが、実際に私がドキュメントから解決したとマークされていたことが分かりました、ありがとう! – joel