サービスコール(実際にはngrx/storeの@Effects)で遅延間隔を長くして再試行パターンを採用しようとしています。私は1コールの作業コードを思いついたので(最適化されていないように見えますが、私の質問ではこれに集中したくはありません)、カスタムObservable演算子にそれを抽出して繰り返し使用したいと思います私のすべてのサービスコールで。最初のカスタムオペレータでrxjs/Observableを正しく拡張する方法
新しい演算子のAPI /使用法を設計する方法と、それをTypeScriptで認識させる方法については空白です。
おそらく、以下のコードはうまくいきません。おそらく、多数の問題が蓄積されているからです。
ので、次のように今私は、コール/効果を持つ:
@Effect()
loadData$: Observable<Action> = this.actions$
.ofType(ActionTypes.LOAD_DATA)
.pluck('payload')
.switchMap(params => {
return this.myService.getData(params)
.map(res => new LoadDataCompleteAction(res))
// ...and this part would have to be extracted:
.retryWhen(attempts => Observable
.zip(attempts, Observable.range(1, 5))
.flatMap((n, i) => {
if (i < 4) {
return Observable.timer(1000 * i);
} else {
throw(n);
}
})
)
})
.catch(err => Observable.of(new LoadDataFailed()));
と私は後にしていますが、他の効果で再試行一部を再利用し、下記のと同様のパターンを持つことができることです。
@Effect()
loadData$: Observable<Action> = this.actions$
.ofType(ActionTypes.LOAD_DATA)
.pluck('payload')
.switchMap(params => {
return this.myService.getData(params)
.map(res => new LoadDataCompleteAction(res))
.retryWhen(attempts => Observable.retryOrThrow(attempts, maxAttempts)
// or maybe - that's my design question
.retryOrThrow(attempts, maxAttempts)
})
.catch(err => Observable.of(new LoadDataFailed()));
遅延コールバックパターン(i * 1000
)は、アプリケーション全体で一定であると想定できます。
以下のコードは私の試みですが、明らかに機能しません。
declare module 'rxjs/Observable' {
interface Observable<T> {
retryOrThrow<T>(attempts: any, max: number): Observable<T>;
}
}
Observable.prototype.retryOrThrow = function(attempt, max) {
console.log('retryOrThrow called');
return Observable.create(subscriber => {
const source = this;
const subscription = source.subscribe(() => {
// important: catch errors from user-provided callbacks
try {
subscriber
.zip(attempt, Observable.range(1, max + 1))
.flatMap((n, i) => {
console.log(n, i);
if (i < max) {
return Observable.timer(1000 * i);
} else {
throw(n);
}
});
} catch (err) {
subscriber.error(err);
}
},
// be sure to handle errors and completions as appropriate and send them along
err => subscriber.error(err),
() => subscriber.complete());
// to return now
return subscription;
});
};
- 私はここで最高の合うだろうか構文、new演算子のためのAPIを設計する方法がわからないです。
- 新しい演算子とObservable名前空間またはモジュールを正しく宣言する方法、TypeScriptが新しいものを認識する方法がわかりません。
更新サービスコール:
getMocky(){
const u = Math.random();
const okUrl = 'http://www.mocky.io/v2/58ffadf71100009b17f60044';
const erUrl = 'http://www.mocky.io/v2/58ffae7f110000ba17f60046';
return u > 0.6 ? this.http.get(okUrl) : this.http.get(erUrl);
}
これはすばらしいことです!どうもありがとうございます!なぜこのページでこの簡単な方法について言及していないのだろうか?https://github.com/ReactiveX/rxjs/blob/master/doc/operator-creationmd – user776686
実際には、このコードに問題があります。メインのエフェクトチェーンにアタッチすると、試行回数は決してリセットされないようです。サービスコールにアタッチされると、実際にはコールは再試行されません。私はケースを分離しようとします。しかし、アイデアごとに - 私はまだ正しい答えを維持しています。 – user776686
switchMapの外ではなくletの直後にキャッチしようとしてください。私はあなたの効果が、letの内側にスローされた後、死にます。 – mtx