在可管道 rxjs 运算符的组合管道中捕获错误
Catch error in combined pipe of pipeable rxjs operators
我们刚刚将我们的一个应用程序升级到 Angular 5,并开始过渡到 rxjs v5.5 中引入的 lettable operators。
因此,我们使用 .pipe()
运算符将可观察管道重写为新语法。
我们之前的代码看起来是这样的,在 .switchMap()
中有一个 .catch()
,以便在抛出错误时不会中断效果的 运行。
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.map((action: LoadData) => action.payload)
.withLatestFrom(this.store.select(getCultureCode))
.switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)
.map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
})
.catch((err, caught) => {
return Observable.empty();
});
);
如果在对 dataService
的调用中抛出错误,它将被捕获并处理(此处简化了错误处理)。
有了 .pipe()
的新语法和用法,我们现在有了这个
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)),
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
})
);
我如何以类似的方式使用新语法捕获可观察管道中抛出的任何错误?
重构后,您将 map
移出 switchMap
投影,因此任何错误都会关闭外部流。为了使两个流保持等效,您需要在投影本身中使用 pipe
,如下所示:
import { EMPTY } from 'rxjs;
// ...
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) =>
this.dataService.loadData(payload, cultureCode)
.pipe(
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
}),
catchError((err, caught) => {
return EMPTY;
})
)
)
);
你也可以这样做。
import { of } from 'rxjs';
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) =>
this.dataService.loadData(payload, cultureCode)
.pipe(
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
}),
catchError(err => of('error', err))
)
)
);
我们刚刚将我们的一个应用程序升级到 Angular 5,并开始过渡到 rxjs v5.5 中引入的 lettable operators。
因此,我们使用 .pipe()
运算符将可观察管道重写为新语法。
我们之前的代码看起来是这样的,在 .switchMap()
中有一个 .catch()
,以便在抛出错误时不会中断效果的 运行。
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.map((action: LoadData) => action.payload)
.withLatestFrom(this.store.select(getCultureCode))
.switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)
.map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
})
.catch((err, caught) => {
return Observable.empty();
});
);
如果在对 dataService
的调用中抛出错误,它将被捕获并处理(此处简化了错误处理)。
有了 .pipe()
的新语法和用法,我们现在有了这个
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)),
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
})
);
我如何以类似的方式使用新语法捕获可观察管道中抛出的任何错误?
重构后,您将 map
移出 switchMap
投影,因此任何错误都会关闭外部流。为了使两个流保持等效,您需要在投影本身中使用 pipe
,如下所示:
import { EMPTY } from 'rxjs;
// ...
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) =>
this.dataService.loadData(payload, cultureCode)
.pipe(
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
}),
catchError((err, caught) => {
return EMPTY;
})
)
)
);
你也可以这样做。
import { of } from 'rxjs';
@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
map((action: LoadData) => action.payload),
withLatestFrom(this.store.select(getCultureCode)),
switchMap(([payload, cultureCode]) =>
this.dataService.loadData(payload, cultureCode)
.pipe(
map(result => {
if (!result) {
return new LoadDataFailed('Could not fetch data!');
} else {
return new LoadDataSuccessful(result);
}
}),
catchError(err => of('error', err))
)
)
);