37

我们刚刚将我们的一个应用程序升级到 Angular 5,并开始转换为rxjs v5.5 中引入的 lettable运算符。

因此,我们使用.pipe()运算符将​​可观察管道重写为新语法。

我们之前的代码看起来像这样,如果抛出错误,则.catch()内部的as 不会中断效果的运行。.switchMap()

@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);
    }
  })
  );

如何以类似的方式使用新语法捕获可观察管道中的任何抛出错误?

4

2 回答 2

61

重构后,您移出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;
         })
      )
  )
);
于 2017-11-16T08:51:20.980 回答
0

你也可以这样做。

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))
      )
  )
);
于 2021-04-21T17:10:02.117 回答