我是Android新手,但是从iOS世界开始,我广泛使用RxSwift并发现了一种我觉得非常奇怪的行为。
我将一个改装调用封装到一个RxJava Observable
(我没有使用RxJavaCallAdapterFactory
,但我真的认为这不是问题。)
fun SearchService.rx_myObjects(query: String?): Observable<List<MyClass>> {
return Observable.create { observer ->
val request = getMyObjects(query = query)
request.enqueue(object : Callback<MyClass>() {
override fun onSuccess(result: MyClass) {
Log.v("TEST", "is unsubscribed ${observer.isUnsubscribed} for query $query")
observer.onNext(result)
observer.onCompleted()
}
override fun onError(error: APIError) {
observer.onError(error)
}
})
}
}
虽然我怀疑在取消订阅该观察者时要调用onNext
NOT ,但似乎并非如此
08-04 11:50:39.767 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed false for query par
08-04 11:50:44.264 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed true for query pari
08-04 11:50:44.653 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed false for query par
08-04 11:50:46.358 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed false for query pari
08-04 11:50:47.990 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed false for query pari
08-04 11:50:48.033 5107-5107/com.mydomain.myapp V/TEST: is unsubscribed true for query par
你可以看到最后一个电话是取消订阅的(你在这里看不到但是它发生了,因为我有par
个结果而不是pari
个结果doOnNext
即使取消订阅,我的观察也会执行封闭。
我已经深入互联网并发现this似乎描述了同样的问题,除了我根本没有使用cache
。
这是我的订阅电话:
private fun retrieveMyObjects(query: String?) {
subscription = service.rx_myObjects(query = query)
.doOnError { showError(it) }
.doOnNext { this.airports = it }
.subscribe()
}
并在textView更新
上触发对象调用search_view.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextChange(newText: String?): Boolean {
subscription?.unsubscribe()
retrieveMyObjects(newText)
return true
}
})
有什么建议吗?我在这里错过了什么吗?
答案 0 :(得分:1)
在最坏的情况下:您执行http呼叫。然后,如果文本更改,您取消订阅以前的订阅,然后执行另一个http调用。但是,第一个http调用的响应只会产生。
这就是你有这种日志订单的原因。由于你有Observable
的取消订阅,它不应该发出新值。为此,您可以在if
/ onNext
块之前添加简单的oncompleted
:
request.enqueue(object : Callback<MyClass>() {
override fun onSuccess(result: MyClass) {
if(!observer.isUnsubscribed()) {
Log.v("TEST", "is unsubscribed ${observer.isUnsubscribed} for query $query")
observer.onNext(result)
observer.onCompleted()
}
}
override fun onError(error: APIError) {
if(!observer.isUnsubscribed()) {
observer.onError(error)
}
}
})
像这样,你可以避免发出一个不会被后续处理的值(当你取消订阅时)
请注意,您正在使用Observable.create
:您可能会因为必须管理很多事情而避免使用它,例如Rx合同,取消订阅,背压。因此,您可以按照建议使用RxJavaCallAdapterFactory
,或尝试Observable.fromAsync
。