Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS中的自愈错误处理_Javascript_Node.js_Rxjs_Observable_Rxjs6 - Fatal编程技术网

Javascript RxJS中的自愈错误处理

Javascript RxJS中的自愈错误处理,javascript,node.js,rxjs,observable,rxjs6,Javascript,Node.js,Rxjs,Observable,Rxjs6,我是RxJS的新手 我有一个承诺的基本HTTP客户端。它有一个login()方法,该方法从服务器获取令牌,并将其存储在内部以供其他方法使用 当令牌过期时,服务器将响应401HTTP错误,在这种情况下,我想再次调用login()并重试请求。另外,请重试其他类型的错误 我不知道如何在RxJS中建模,我已经有了一些工作,但我希望有更好的方法来实现 (这是在一个应用于所有需要身份验证的方法的装饰器中,此处为wrappedFunc) RxJS中这种错误处理的惯用方法是什么?间隔(100)每100毫秒发出一

我是RxJS的新手

我有一个承诺的基本HTTP客户端。它有一个login()方法,该方法从服务器获取令牌,并将其存储在内部以供其他方法使用

当令牌过期时,服务器将响应401HTTP错误,在这种情况下,我想再次调用login()并重试请求。另外,请重试其他类型的错误

我不知道如何在RxJS中建模,我已经有了一些工作,但我希望有更好的方法来实现

(这是在一个应用于所有需要身份验证的方法的装饰器中,此处为wrappedFunc

RxJS中这种错误处理的惯用方法是什么?

间隔(100)
每100毫秒发出一次,并且
开关映射将取消正在进行的订阅并重新订阅,因此如果
wrappedFunc
调用需要超过100毫秒,它将永远不会“发生”-它将尝试一次又一次地进行调用

我想你还需要更多这样的东西:

return defer(() => wrappedFunc.apply(this, args))
  .pipe(
    retryWhen(errors$ => errors$.pipe(
      switchMap((error) => {
        if (error.response.status === 401) {
          return this.login()
        } else {
          return of(error)
        }
      }),
      scan((attempts, currentError) => {
        if (attempts > 5) {
          throw currentError
        }
        return attempts + 1
      }, 0),
      delay(100),
    ))
  );

此处的
延迟
用作包装器,因此
wrappedFunc
可以返回承诺或可观察,而
延迟
用于延迟重试。

为什么
间隔(100)
?这是不是要推迟wrappedFunc的电话?啊!这是每100毫秒重试一次,我的印象是它会立即发出,然后等待100毫秒,然后再次发出,但是看着文档,似乎我错了!:)添加startWith(0)似乎可以解决此问题。
return defer(() => wrappedFunc.apply(this, args))
  .pipe(
    retryWhen(errors$ => errors$.pipe(
      switchMap((error) => {
        if (error.response.status === 401) {
          return this.login()
        } else {
          return of(error)
        }
      }),
      scan((attempts, currentError) => {
        if (attempts > 5) {
          throw currentError
        }
        return attempts + 1
      }, 0),
      delay(100),
    ))
  );