而不是
我有这段代码来尝试连接到xmpp服务器。一切正常,除了在最后一次尝试连接时,onError 不会在订阅者上调用,根据文档,它应该。我做错了什么?
@Override
public void connect(final AbstractXMPPConnection connection) {
Observable.<AbstractXMPPConnection>create(subscriber -> {
try {
connection.connect();
} catch (SmackException | IOException | XMPPException e) {
e.printStackTrace();
subscriber.onError(e);
}
})
.retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {
return Observable.timer(i, TimeUnit.SECONDS);
}))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<AbstractXMPPConnection>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (callback != null)
callback.onFailedConnecting();
}
@Override
public void onNext(AbstractXMPPConnection conn) {
if (callback != null)
callback.onConnected();
}
});
}
TLDR:在最后一次尝试时,应该调用公共无效错误,
你有:
.retryWhen(attempts -> attempts.zipWith(Observable.range(1, 4), (n, i) -> i).flatMap(i -> {
return Observable.timer(i, TimeUnit.SECONDS);
}))
此代码永远不会发出错误,因此它将以指数方式(计时器)尝试重试,但永远不会失败。因此,onError() 永远不会被调用。
如果你想捕捉错误,你需要用一个明确的 Observable.error() 从 retryWhen 传递它,或者删除 retryWhen 部分。 :)
我这样做了(Scala,RxScala):
.retryWhen(_
.zipWith(Observable.just(1, 2, 3, -1))((t, i) => (t, i))
.flatMap( tuple => tuple match {
case (t, -1) => Observable.error(t)
case (t, i) => Observable.timer(i seconds)
}))
也许有某种zipWith
运算符,它调用 onError
,具有第一个非配对元素。那就太好了