加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular 2 Http RetryWhen

发布时间:2020-12-17 17:02:21 所属栏目:安全 来源:网络整理
导读:我正在尝试在HTTP调用中使用retryWhen. 尝试使用时,它完美地工作: return this.http.get(`${environment.apiUrl}/track/${this.user.instance._id}/${this.currentPlayer.playlist.id}/next?s=${this.playerCounter}`,options) .timeout(500,new TimeoutErr
我正在尝试在HTTP调用中使用retryWhen.

尝试使用时,它完美地工作:

return this.http.get(`${environment.apiUrl}/track/${this.user.instance._id}/${this.currentPlayer.playlist.id}/next?s=${this.playerCounter}`,options)
      .timeout(500,new TimeoutError(`Timeout trying to get next track. [instanceId=${this.user.instance._id}]`))
      .retryWhen(attempts => {
        return Observable.range(1,3).zip(attempts,i => i).flatMap(i => 3 === i ? Observable.throw(attempts) : Observable.timer(i * 1000));
      })

如果出现超时错误,最多会尝试3次.

但是,总是有一个buuut,我想让它更抽象地用于各种用例,为此,我必须检查错误的类型.

只会重试TechnicalErros.

所以我尝试了这个没有成功.

.retryWhen(attempts => {
    return attempts.flatMap(error => {
      if(error instanceof TechnicalError) {
        return Observable.range(1,i => i).flatMap(i => 3 === i ? Observable.throw(attempts) : Observable.timer(i * 1000));
      } else {
        Observable.throw(error);
      }
    });
  })

它在第一次尝试时停止,并且不执行Observable.timer(),也不执行Observable.throw().

我几乎可以肯定问题是关于第一个flatMap,我已经尝试使用mergeMap,但没有成功.

提前致谢!

解决方法

在RxJS 5中,flatMap()只是mergeMap():)的别名.

问题在于您使用retryWhen()运算符的回调方式.它只被调用一次,然后每当一个错误信号到达时它被推送到从这个回调返回的Observable.

在你的第二个例子中,你从attempts.flatMap返回Observable,然后再次使用.zip(attempts,i => i)订阅回调.但是这个zip运算符永远不会被调用,因为它在calculate.flatMap已经消耗了值之后被调用.这就是为什么Observable.range(1,3)始终从头开始.

我知道这看起来令人困惑.请注意:

> retryWhen()的回调只被调用一次.
>每次出现错误时都会调用attempt.flatMap()的回调.

因此,您只需重新构建代码,例如:

var source = Observable.create(obs => {
        obs.next(1);
        obs.next(2);
        obs.error(new TechnicalError('error from source'));
    })
    .retryWhen(attempts => {
        console.log('retryWhen callback');
        let count = 0;

        return attempts.flatMap(error => {
            if (error instanceof TechnicalError) {
                console.log(error);
                return ++count >= 3 ? Observable.throw(error) : Observable.timer(count * 1000);
            } else {
                return Observable.throw(error);
            }
        });
    })
    .subscribe(
        val => console.log(val),err => console.log('subscribe error',err),_ => console.log('complete')
    );

这打印到控制台:

1
2
retryWhen callback
TechnicalError { msg: 'error from source' }
1
2
TechnicalError { msg: 'error from source' }
1
2
TechnicalError { msg: 'error from source' }
subscribe error TechnicalError { msg: 'error from source' }

观看现场演示:https://jsbin.com/hobeda/3/edit?js,console

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读