使用RxJava2在Kotlin中指数退避

时间:2018-02-22 10:48:37

标签: kotlin rx-java2

我正在尝试对请求进行指数重试,这样如果请求失败(即您的互联网已关闭),应用会无休止地重试,直到它正常工作(应用程序位于前台的时间)

我尝试了this solution

    public class RetryWithDelay implements Function<Observable<? extends Throwable>, Observable<?>> {
    private final int maxRetries;
    private final int retryDelayMillis;
    private int retryCount;

    public RetryWithDelay(final int maxRetries, final int retryDelayMillis) {
        this.maxRetries = maxRetries;
        this.retryDelayMillis = retryDelayMillis;
        this.retryCount = 0;
    }

    @Override
    public Observable<?> apply(final Observable<? extends Throwable> attempts) {
        return attempts
                .flatMap(new Function<Throwable, Observable<?>>() {
                    @Override
                    public Observable<?> apply(final Throwable throwable) {
                        if (++retryCount < maxRetries) {
                            // When this Observable calls onNext, the original
                            // Observable will be retried (i.e. re-subscribed).
                            return Observable.timer(retryDelayMillis,
                                    TimeUnit.MILLISECONDS);
                        }

                        // Max retries hit. Just pass the error along.
                        return Observable.error(throwable);
                    }
                });
    }
}

但是当我尝试将其转换为kotlin时,它表示Function只接受一个通用参数。

1 个答案:

答案 0 :(得分:2)

我将Java代码复制粘贴到IntelliJ中,它为我完成了一半的工作:

import java.util.concurrent.TimeUnit
import io.reactivex.functions.Function
import io.reactivex.*

class RetryWithDelay(private val maxRetries: Int, private val retryDelayMillis: Long) : Function<Observable<Throwable>, Observable<Long>> {

    override fun apply(attempts: Observable<Throwable>): Observable<Long> {
        return attempts
                .flatMap(object : Function<Throwable, Observable<Long>> {

                    private var retryCount: Int = 0

                    override fun apply(throwable: Throwable): Observable<Long> {
                        return if (++retryCount < maxRetries) {
                            // When this Observable calls onNext, the original
                            // Observable will be retried (i.e. re-subscribed).
                            Observable.timer(retryDelayMillis,
                                    TimeUnit.MILLISECONDS)
                        } else Observable.error<Long>(throwable)

                        // Max retries hit. Just pass the error along.
                    }
                })
    }
}

请注意,retryCount已移至内部flatMap中,因此不会在多个Observer之间共享。