PublishSubject with kotlin coroutines (Flow)

被刻印的时光 ゝ 提交于 2020-01-02 02:37:05

问题


I'm trying to refactor a piece of code from RX to coroutines but despite all my efforts I think I'm getting lost.

So I had PublishSubject created and i was sending messages to it and also I was listening for results. It worked flawlessly, but now I'm not sure how to do the same thing with coroutines (flows or channels).

private val subject = PublishProcessor.create<Boolean>>()

...

fun someMethod(b: Boolean) {
    subject.onNext(b)
}

fun observe() {
    subject.debounce(500, TimeUnit.MILLISECONDS)
           .subscribe {
         // value received
    }
}

Since i need debounce operator i really wanted to do the same thing with flows so I created channel and then I tried to create flow from that channel and listen to changes, but I'm not getting any results.

private val channel = Channel<Boolean>()

...

fun someMethod(b: Boolean) {
    channel.send(b)
}

fun observe() {
    flow {
         channel.consumeEach { value ->
            emit(value)
         }
    }.debounce(500, TimeUnit.MILLISECONDS)
    .onEach {
        // value received
    }
}

What do I have wrong?


回答1:


Flow is a cold asynchronous stream, just like an Obserable.

All transformations on the flow, such as map and filter do not trigger flow collection or execution, only terminal operators (e.g. single) do trigger it.

The onEach method is just a transformation. Therefore you should replace it with the terminal flow operator collect. Also you could use a BroadcastChannel to have cleaner code:

private val channel = BroadcastChannel<Boolean>(1)

suspend fun someMethod(b: Boolean) {
    channel.send(b)
}

suspend fun observe() {
  channel
    .asFlow()
    .debounce(500, TimeUnit.MILLISECONDS)
    .collect {
        // value received
    }
}



回答2:


ArrayBroadcastChannel in Kotlin coroutines is the one most similar to PublishSubject.

  1. Like PublishSubject, an ArrayBroadcastChannel can have multiple subscribers and all the active subscribers are immediately notified.
  2. Like PublishSubject, events pushed to this channel are lost, if there are no active subscribers at the moment.

Unlike PublishSubject, backpressure is inbuilt into the coroutine channels, and that is where the buffer capacity comes in. This number really depends on which use case the channel is being used for. For most of the normal use cases, I just go with 10, which should be more than enough. If you push events faster to this channel than receivers consuming it, you can give more capacity.



来源:https://stackoverflow.com/questions/56111292/publishsubject-with-kotlin-coroutines-flow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!