我有EditText
用户输入搜索查询,我想在用户输入内容时在我的服务器上执行即时搜索。
我尝试使用RxJava
执行此操作,如下所示:
RxTextView.textChanges(editQuery) // I'm using RxBinding for listening to text changes
.flatMap(new Func1<CharSequence, Observable<UserPublic[]>>() {
@Override
public Observable<UserPublic[]> call(CharSequence query) {
return api.searchUsers(query); // I'm using Retrofit 1.9 for network calls. searchUsers returns an Observable<UserPublic[]>
}
})
.subscribe(Observers.create(
new Action1<UserPublic[]>() {
@Override
public void call(UserPublic[] userPublics) {
processResult(userPublics);
}
})
, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
processError(throwable);
}
});
问题是如果网络调用遇到错误,整个observable都会停止。因此,当用户继续输入时,没有任何反应。
如何修改此代码,以便:
processError
processResult
/ processError
)答案 0 :(得分:2)
使用retryWhen()
运算符并在订阅之前将其附加到可观察链。请注意,retryWhen()
的参数是一个带Observable<Throwable>
并返回Observable<?>
的函数。返回的类型无关紧要,因为运算符使用onNext()
结果启动重试,onError()
或onCompleted()
结果终止链。
这是一个等待5秒并再次尝试的天真应用程序:
observable
.retryWhen( errorObservable -> errorObservable.delay( 5, TimeUnit.SECONDS ) )
.subscribe();
这是一个不那么天真的操作,会在超时时重试,如果发生IOException
则会失败:
observable
.retryWhen( errorObservable -> errorObservable.flatMap( throwable -> { // (1)
if ( throwable instanceof IOException ) {
return Observable.error( throwable ); // (2)
}
return Observable.just(1); // (3)
} )
.subscribe();
flatMap()
可以让您推迟决定,直到您知道要处理的是哪种错误。onNext()
的观察者告诉retryWhen()
运营商重新订阅原始观察结果。答案 1 :(得分:0)
我建议您查看RxJava文档中的Error Handling Operators页面。尝试与不同的操作员一起提出最适合您的用例的操作员。我认为您应该使用onErrorResumeNext()
返回的某种默认值,例如返回new UserPublic[0]
。在这里调用processError
会有问题,特别是如果它处理UI,因为您可能仍在后台线程上进行处理。