angular - RxJS mergeMap 运算符中的错误处理

标签 angular rxjs observable subscription angular-httpclient

当我使用 Angular HttpClient 发出 GET 请求时,我会得到一个 observable 并在 RxJS 运算符 mergeMap 中处理它。

现在它一次又一次地抛出 404,我想捕获它。最后,浏览器控制台中不应出现错误消息,管道应使用流的下一个值进行处理。

有没有可能?我没有用 catchError() 来管理它。

这是我的代码的简化版本:

    ...
    this.service1.getSomeStuff().pipe(
          mergeMap((someStuff) => {
            return from(stuff);
          }),
          mergeMap((stuff) => {
            return this.service2.getMoreStuff(stuff.id); // Here I need some error handling, if 404 occurs
          }),
          mergeMap((things) => {
            return from(things).pipe(
              mergeMap((thing) => {
                if (allLocations.some(x => x.id === metaData.id)) {
                  return this.service2.getMore(thing.id, thing.type, thing.img_ref);
                }
              }),
              map((thing) => {
              ...

更新:添加了 catchError() 的方法

我这样试过了,但是没有检测到错误,下一个 mergeMap 不起作用(IDE 不再识别像 thing.id、thing.type、th​​ing.img_ref 这样的参数):
...
this.service1.getSomeStuff().pipe(
      mergeMap((someStuff) => {
        return from(stuff);
      }),
      mergeMap((stuff) => {
        return this.service2.getMoreStuff(stuff.id).pipe(
          catchError(val => of(`Error`))
        );
      }),
      mergeMap((things) => {
        return from(things).pipe(
          mergeMap((thing) => {
            if (allLocations.some(x => x.id === metaData.id)) {
              return this.service2.getMore(thing.id, thing.type, thing.img_ref);
            }
          }),
          map((thing) => {
          ...

最佳答案

您需要使用 retryretryWhen (名称是不言自明的)——这些操作符将重试失败的订阅(一旦发出错误,就重新订阅源 observable。

提高id每次重试时——您可以将其锁定在一个范围内,如下所示:

const { throwError, of, timer } = rxjs;
const { tap, retry, switchMap } = rxjs.operators;

console.log('starting...');

getDetails(0)
  .subscribe(console.log);


function getDetails(id){
  // retries will restart here
  return of('').pipe(
    switchMap(() => mockHttpGet(id).pipe(
      // upon error occurence -- raise the id
      tap({ error(err){
        id++;
        console.log(err);
      }})
    )),  
    retry(5) // just limiting the number of retries
             // you could go limitless with `retry()`
  )
}

function mockHttpGet(id){
  return timer(500).pipe(
    switchMap(()=>
      id >= 3
      ? of('success: ' + id)
      : throwError('failed for ' + id)
    )
  );
}
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>


请注意,使用条件 retry 会更明智。仅重试 404错误。这可以通过 retryWhen 实现,例如

// pseudocode
retryWhen(errors$ => errors$.pipe(filter(err => err.status === '404')))

检查这个 article on error handling in rxjsretry 变得更富裕和 retryWhen .

希望这可以帮助

更新 :还有其他方法可以实现:

const { throwError, of, timer, EMPTY } = rxjs;
const { switchMap, concatMap, map, catchError, take } = rxjs.operators;

console.log('starting...');

getDetails(0)
  .subscribe(console.log);


function getDetails(id){
  // make an infinite stream of retries
  return timer(0, 0).pipe(
    map(x => x + id),
    concatMap(newId => mockHttpGet(newId).pipe(
      // upon error occurence -- suppress it
      catchError(err => {
        console.log(err);
        // TODO: ensure its 404

        // we return EMPTY, to continue
        // with the next timer tick
        return EMPTY;
      })
    )),
    // we'll be fine with first passed success
    take(1)
  )
}

function mockHttpGet(id){
  return timer(500).pipe(
    switchMap(()=>
      id >= 3
      ? of('success: ' + id)
      : throwError('failed for ' + id)
    )
  );
}
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>

关于angular - RxJS mergeMap 运算符中的错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55727696/

相关文章:

angular - Linq First相当于TypeScript+rxjs

angular - 等待 rxjs 中的内部可观察值

import - 用于 Observable 的 Angular 2 导入共享运算符

angular - RxJs Observable - 通过发出默认值处理 404

JavaFX SimpleObjectProperty<T> 与 SimpleTProperty

javascript - angular2 服务基类继承 - 为什么 'this' 为空?

javascript - AngularFire2 - 如何在页面刷新后保持登录状态

css - _ngcontent-c0 自动添加到 CSS 规则中

typescript - Observable 数组的 Observable 数组

javascript - Angular 和 React 等语言的 SEO 现状?