RxJS 6の新しいバージョンと、特にパイプオペレーターの操作。現在、パイプを使用してAPI呼び出しの結果を取得し、それらを一連の追加タスクに渡します。
すべて問題なく動作しますが、問題が発生した場合にパイプをキャンセルまたは終了する方法を見つけることができないようです。たとえば、値がnullかどうかを確認するためにタップ演算子を使用しています。次にエラーをスローしますが、パイプは次のタスク(この場合は連結マップ)に移動しているように見えます。
したがって、パイプを途中で終了またはキャンセルするにはどうすればよいですか?前もって感謝します。
getData(id: String): Observable<any[]> {
return this.http.get<any>(`${this.baseUrl}/path/${id}`).pipe(
tap(evt => {
if (evt == null) {
return throwError(new Error("No data found..."));
}
}),
concatMap(
evt =>
<Observable<any[]>>(
this.http.get<any[]>(
`${this.baseUrl}/path/relatedby/${evt.child_id}`
).map(res =>( {"response1":evt, "response2":res}) )
)
),
retry(3),
catchError(this.handleError("getData", []))
);}
このstackblitzで持っているものから基本的なコンセプトを試してみましたが、うまくいきました。残りの操作はキャンセルされました。以下のリンクを参照してください。
https://stackblitz.com/edit/angular-4ctwsd?file=src%2Fapp%2Fapp.component.ts
私のコードと私の違いは、throw
ではなくthrowError
を使用したことです(それはあなたが書いたものですか)。私は単にエラーをスローしています...スローされたエラーを返しません。
参照用のコードは次のとおりです。
import { Component } from '@angular/core';
import { of, from } from 'rxjs';
import { map, catchError, tap, retry} from 'rxjs/operators';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular 6';
constructor() {
of('a', 'b', 'c', 'd')
.pipe(
map(x => {
if (x === 'c') {
throw 'An error has occurred';
}
return x;
}),
tap(x => console.log('In tap: ', x)),
retry(3),
catchError(() => of('caught error!'))
)
.subscribe(x => console.log(x));
}
}
シグナルSubject
とrxjs演算子を使用して、パイプをキャンセル/終了することもできます:takeUntil
例
httpGetSafe(path: string): Observable<Data> {
const stopSignal$ = new Subject();
return this.http.get<Data>(path).pipe(
map(data => {
const isBad = data === null;
if (isBad) {
stopSignal$.next();
}
return data;
}),
takeUntil(stopSignal$)
);
}
エラーをスローするよりも少しシンプルで柔軟な場合があります...