网络求情重试-RetryWhen

我们在向后台请求数据的的时候,有时候可能会发现异常的情况,可能会要求你请求3次或者更多次,比如扫码登录的时候,我们可能会要求每隔几秒就需要去查询当前的扫码的状态,这也需以便确定是不是已经登录成功,要多次不断的去发送请求,多次求情的时候为了使代码更优雅的实现,我们可以利用rxjava的RetryWhen来实现。

RetryWhen这个操作符的作用是当观察者发送异常的时候,该方法会被调用,在这个方法中我们会根据我们的逻辑来判断是继续抛出这个异常,还是重新订阅观察者,这么说可能比较模糊,看下列子:

 var count: Int = 0
 Observable.create(ObservableOnSubscribe<String> { emitter ->
      count ++
      Log.i(TAG, "onCreate:  创造数字$count")
      emitter?.onNext("$count")
  }).flatMap {
          if(it.toInt() < 100){
              Observable.error(Exception())
          }else{
              Observable.just(it)
          }
      }.retryWhen {
          it.flatMap {
              throwable ->
                if(throwable is Exception){
                    Observable.timer(2, TimeUnit.SECONDS)
                }else{
                    Observable.error(throwable)
                }
          }
      }
  .subscribe({
      Log.i(TAG, "subscribe: $it")
  }, {
              Log.i(TAG, "subscribe: $it")
   })
}

这个会一直执行,直到count的值为100,之后抛出异常,执行subscribe,程序终止。
RetryWhen这个操作符的作用就是当接收到异常或者错误的时候将会执行RetryWhen这个操作符,这个操作符里面的返回的事件决定了是不是会重新订阅,如果返回的是onCompleted或者onError则不会重新订阅,如果返回的是onNext,则表示订阅该事件。

为了以后用起来简单,我们可以利用transform抽象出来一个通用的重试类:

import io.reactivex.*
import io.reactivex.functions.Function
import org.reactivestreams.Publisher
import java.util.concurrent.TimeUnit

class RetryWhenTransformer<T>(private var count: Int, private val time:Long) : ObservableTransformer<T, T>, FlowableTransformer<T, T>,
    SingleTransformer<T, T>, MaybeTransformer<T, T> {

    private fun retryObservableFunction(): Function<Observable<Throwable>, ObservableSource<Any>> {
        return Function { t ->
            t!!.flatMap { throwable ->
                count--
                if (count < 0) {
                    Observable.error(throwable)
                } else {
                    Observable.timer(time.toLong(), TimeUnit.SECONDS)
                }
            }
        }
    }

    private fun retryFlowableFunction(): Function<Flowable<Throwable>, Publisher<Any>> {
        return Function {
            it.flatMap { throwable ->
                count--
                if (count < 0) {
                    Flowable.timer(time, TimeUnit.SECONDS)
                } else {
                    Flowable.error(throwable)
                }
            }

        }
    }

    override fun apply(upstream: Observable<T>?): Observable<T>? {
        return upstream?.retryWhen(retryObservableFunction())
    }

    override fun apply(upstream: Flowable<T>?): Flowable<T>? {
        return upstream?.retryWhen(retryFlowableFunction())
    }

    override fun apply(upstream: Single<T>?): Single<T>? {
            return upstream?.retryWhen(retryFlowableFunction())
    }

    override fun apply(upstream: Maybe<T>?): Maybe<T>? {
        return upstream?.retryWhen(retryFlowableFunction())
    }

重写这个类ObservableTransformer<T, T>, FlowableTransformer<T, T>,
SingleTransformer<T, T>, MaybeTransformer<T, T> 实现对应的apply方法就ok了。
调用的时候还需要传入次数和间隔时间即可:如果不确定次数的话可以穿一个极大值 比如 Int.MAX_VALUE

var count: Int = 0
  Observable.create(ObservableOnSubscribe<String> { emitter ->
              count ++
              Log.i(TAG, "onCreate:  创造数字$count")

              emitter?.onNext("$count")
          })
              .flatMap {
                  if(it.toInt() < 100){
                      Observable.error(Exception())
                  }else{
                      Observable.just(it)
                  }
              }
              .compose(RetryWhenTransformer(4, 2))
          .subscribe({
              Log.i(TAG, "subscribe: $it")
          },
                  {
                      Log.i(TAG, "subscribe: $it")
                  })

        }
    }

结果如下:

I/MainActivity: onCreate:  创造数字1
I/MainActivity: onCreate:  创造数字2
I/MainActivity: onCreate:  创造数字3
I/MainActivity: onCreate:  创造数字4
I/MainActivity: onCreate:  创造数字5
I/MainActivity: subscribe: java.lang.NumberFormatException: For input string: "test-5"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟红尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值