• RxJS 系列 – Error Handling Operators


    前言

    前几篇介绍过了 

    Creation Operators

    Filter Operators

    Join Creation Operators

    这篇继续介绍 Error Handling Operators.

    参考

    RxJS 錯誤處理 Operators (1) - catchError / finalize / retry / retryWhen

    Docs – Error Handling Operators

    Observable and Subscriber Handler Error

    Observable 的流程是 : Observable init > pipe > subscribe

    不经过 pipe 的情况下, 处理 error 的方式如下:

    const obs = new Observable(subscriber => {
      subscriber.error('error message');
      // throw 'error message'; // throw 也是可以
    });
    obs.subscribe({
      error: errorMessage => console.log(errorMessage), // error message
    });

    简单明了.

    catchError

    catchError 是 pipe 阶段的 error handle. 它是 operator 来的.

    catch error and change to succeeded

    const obs = new Observable(subscriber => {
      subscriber.error('error message');
    });
    obs
      .pipe(
        catchError(error => {
          console.log(error); // error message
          return of('succeeded');
        })
      )
      .subscribe({
        next: value => console.log(value), // succeeded
        error: errorMessage => console.log(errorMessage), // won't call
      });

    catchError 接收到 error 后, 可以有几个处理方式. 上面这个是返回一个 "成功" 的 Observable, 这样 error 就不会在传下去了. 

    catch error and re-throw

    catch error 然后继续往下 throw error,

    throwError 方法之前介绍过了, 它是 Creation Operators 的一员.

    catchError(error => {
      return throwError(() => 're-throw error');
      // throw 're-throw error'; // 用 throw 也可以
    })

    小结

    总之, catchError 要返回一个 Observable, 可以是 succeeded 或者是 error

    catchError(error => {
      if (Math.random() < 0.5) {
        return throwError(() => 're-throw error');
        // throw 're-throw error'; // 用 throw 也可以
      } else {
        return of('succeeded');
      }
    })

    catch error and retry

    除了 succeeded 和 error, 还有一种处理方式是 retry. 所谓 retry 就是 unsubscribe 当前的 stream, 重新 subscribe Observable 得到新的 stream (旧的 Observable 会 displose, 新的会 init)

    catchError((error, caught) => {
        return caught;
    })

    返回 catchError 的第二个参数 caught 就表示要 retry. retry 可能会导致死循环的哦.

    所以必须要有条件, 避开死循环, 比如:

    catchError((error, caught) => {
      if (Math.random() < 0.5) {
        return caught; // retry
      } else {
        return of('succeeded');
      }
    })

    delay retry

    catchError((error, caught) => {
      return timer(2000).pipe(switchMap(() => caught));
    })

    返回一个 delay 的 Observable 就可以延后 retry 了. 这里用了 switchMap 把 timer 的值换成了 caught observable. (这个 operator 我还没有介绍过的)

    retry count

    要计算 count 只能开一个外部的 variable 做记入. 或者封装一个自定义 operator. 但更简单的方法是直接用 RxJS 提供的 retry 和 retryWhen operator. 下面会介绍.

    retry

    用 catchError + caught 实现 retyr 太费劲了, 所以 RxJS 封装了 retry operator

    retry({
      count: 3,
      delay: 2000,
      resetOnSuccess: false,
    })

    count 声明可以 retry 多少次

    delay 声明 retry 的间隔时间, 有时候 error 是因为 server 繁忙, 只要等 1,2 秒在 retry 发 ajax 就可以解决了.

    此外 delay 还支持更复杂的 config. 通过判断 error 和 retryCount 来决定要 delay 多少秒.

    我们甚至可以返回 click$ 让 user 点击触发 retry. 

    也可以直接返回 throwError 结束 retry (即便还没有 hit 到 max retry count), 灵活就对了

    delay: (error, retryCount) => timer(2000 * retryCount)

    resetOnSuccess 声明当 retry 成功以后是否要 reset retry count. 默认值是 false, 通常 reset 是正确的, 所以一般我都是 set 成 true.

    retryWhen

    已经废弃了, 改用 retry + delay option 实现吧.

    一句话总结

    catchError : 在 pipe 中 catch error, 3中处理, 成功, 继续 error, retry

    retry : 用 catchError 做 retry 太费劲就有了 retry operator

    retryWhen : 废弃了, 改用 retry + delay option 实现.

  • 相关阅读:
    HDU 1059 Dividing(多重背包)
    新华网,要厚道
    js与DOM初步:访问html元素
    Hacker News网站的文章排名算法工作原理
    做技术,是个精益求精的事情
    百度贴吧客户端(Android)网络通信行为分析
    Storm同时接收多个源(spout和bolt)
    各种流处理系统的比较
    Kafka学习
    关联规则推荐及Apriori算法
  • 原文地址:https://www.cnblogs.com/keatkeat/p/16748750.html
Copyright © 2020-2023  润新知