gpt4 book ai didi

java - rxjava : Can I use retry() but with delay?

转载 作者:行者123 更新时间:2023-12-03 05:04:55 25 4
gpt4 key购买 nike

我在 Android 应用程序中使用 rxjava 来异步处理网络请求。现在我想仅在经过一定时间后重试失败的网络请求。

有没有办法在 Observable 上使用 retry() 但仅在一定延迟后重试?

有没有办法让 Observable 知道当前正在重试(而不是第一次尝试)?

我查看了 debounce()/throttleWithTimeout() 但他们似乎在做一些不同的事情。

编辑:

我想我找到了一种方法来做到这一点,但我有兴趣确认这是正确的方法或其他更好的方法。

我正在做的是这样的:在 Observable.OnSubscribe 的 call() 方法中,在调用订阅者的 onError() 方法之前,我只是让线程 hibernate 所需的时间。因此,要每 1000 毫秒重试一次,我会执行以下操作:

@Override
public void call(Subscriber<? super List<ProductNode>> subscriber) {
try {
Log.d(TAG, "trying to load all products with pid: " + pid);
subscriber.onNext(productClient.getProductNodesForParentId(pid));
subscriber.onCompleted();
} catch (Exception e) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e.printStackTrace();
}
subscriber.onError(e);
}
}

由于该方法在 IO 线程上运行,因此它不会阻塞 UI。我看到的唯一问题是,即使是第一个错误也会延迟报告,因此即使没有 retry(),延迟也会存在。如果延迟不是在错误发生之后应用,而是在重试之前应用(显然不是在第一次尝试之前),我会更好。

最佳答案

您可以使用 retryWhen() 运算符向任何 Observable 添加重试逻辑。

以下类包含重试逻辑:

RxJava 2.x

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);
}
});
}
}

RxJava 1.x

public class RetryWithDelay implements
Func1<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<?> call(Observable<? extends Throwable> attempts) {
return attempts
.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(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);
}
});
}
}

用法:

// Add retry logic to existing observable.
// Retry max of 3 times with a delay of 2 seconds.
observable
.retryWhen(new RetryWithDelay(3, 2000));

关于java - rxjava : Can I use retry() but with delay?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22066481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com