可观察到的是在没有订阅者的情况下缓冲项目,然后在订阅时发出项目,然后在取消订阅时清除缓冲区吗?

时间:2019-05-16 22:45:42

标签: kotlin rx-java rx-java2

我想要一个可观察到的东西:

  1. 可以按需发射物品,并且永远无法完成(可观察到的热点?)
  2. 知道何时有订阅者
  3. 如果没有订阅者,它将缓冲我告诉它发出的项目
  4. 订阅后,它将依次发出缓冲的项目,然后清除缓冲区,然后继续让我发出更多的项目
  5. 取消订阅时(处置了订阅者吗?),它将返回到缓冲状态。

也:

  1. 预计一次只能有一个订户

  2. 它不必是线程安全的

这是我在想什么的伪代码-虽然没有正确的方式执行此操作,但我没有必要的回调。如果我可以将其全部包装在Observable或Subject中,那也很好。

class RxEventSender {
    private val publishSubject = PublishSubject.create<Action>()

    val observable: Observable<Action> = publishSubject

    private val bufferedActions = arrayListOf<Action>()

    private var hasSubscribers = false

    fun send(action: Action) {
        if (hasSubscribers) {
            publishSubject.onNext(action)
        } else {
            bufferedActions.add(action)
        }
    }

    //Subject was subscribed to -- not a real callback
    fun onSubscribed() {
        hasSubscribers = true
        bufferedActions.forEach {action ->
            publishSubject.onNext(action)
        }
        bufferedActions.clear()
    }

    //Subject was unsubscribed -- not a real callback
    fun onUnsubscribed() {
        hasSubscribers = false
    }
}

2 个答案:

答案 0 :(得分:0)

使用ReplaySubject。如果您担心缓冲区太大,则它具有无边界和无边界版本。

答案 1 :(得分:0)

花了一些时间后,我认为这足以满足我的需求。它并没有很好地包裹在Subject或Observable中,但是我所需要的只是发出项目并订阅。

class RxEventSender<T> {
    private val bufferedEvents = arrayListOf<T>()

    private val publishSubject = PublishSubject.create<T>()

    val observable: Observable<T> = publishSubject
            .mergeWith(Observable.fromIterable(bufferedEvents))
            .doOnDispose {
                bufferedEvents.clear()
            }

    fun send(event: T) {
        if (publishSubject.hasObservers()) {
            publishSubject.onNext(event)
        } else {
            bufferedEvents.add(event)
        }
    }
}