我正在观察由NetworkResource
生成的行,并将其包裹在Observable.create
中。这是代码,缺少try / catch和取消以简化:
fun linesOf(resource: NetworkResource): Observable<String> =
Observable.create { emitter ->
while (!emitter.isDisposed) {
val line = resource.readLine()
Log.i(TAG, "Emitting: $line")
emitter.onNext(line)
}
}
问题在于,稍后我想使用Flowable
将其转换为observable.toFlowable(LATEST)
以添加背压,以防我的消费者无法跟上,但取决于我是如何做到的,消费者在第128项之后停止接收物品。
A)这样一切正常:
val resource = ...
linesOf(resource)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.toFlowable(BackpressureStrategy.LATEST)
.subscribe { Log.i(TAG, "Consuming: $it") }
B)这里消费者在128件商品后卡住(但继续发货):
val resource = ...
linesOf(resource)
.toFlowable(BackpressureStrategy.LATEST)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { Log.i(TAG, "Consuming: $it") } // <-- stops after 128
在选项 A)中,所有内容都可以正常运行,我可以看到Emitting: ...
日志与Consuming: ...
日志并排。
在选项 B)中,我可以看到Emitting: ...
日志消息愉快地发出新行,但我在第128项后停止看到Consuming: ...
日志消息,即使发出继续进行。
问题:有人可以帮我理解为什么会这样吗?
答案 0 :(得分:4)
首先,您使用了错误的类型和错误的运算符。使用Flowable
无需转换。使用Flowable.generate
可以获得背压:
Flowable.generate(emitter -> {
String line = resource.readLine();
if (line == null) {
emitter.onComplete();
} else {
emitter.onNext(line);
}
});
其次,您的版本挂起的原因是由subscribeOn
导致的同一个池死锁。来自下游的请求安排在您急切的排放回路后面,并且无法生效,在默认的128个元素处停止排放。使用Flowable.subscribeOn(scheduler, false)
来避免这种情况。