【问题标题】:Strange behavior of Observable#repeat in reactive extensionsObservable#repeat 在响应式扩展中的奇怪行为
【发布时间】:2017-02-15 20:44:52
【问题描述】:

我在搞乱 rx 运算符,很好奇为什么 just(null).repeat() 不能作为任何内置运算符的参数:

Observable.interval(1, TimeUnit.SECONDS)
    .sample(Observable.just(null).repeat())
    .subscribe(System.out::println);

我原以为这会打印0 1 2 3 ...,但它只是挂起。我想这是因为repeat 占用了默认的Scheduler,但是,如果您交换intervaljust-repeat 的角色,那么它会按预期工作,每秒打印一次null

Observable.just(null).repeat()
    .sample(Observable.interval(1, TimeUnit.SECONDS))
    .subscribe(System.out::println);

这是怎么回事?

【问题讨论】:

    标签: java rx-java reactive-programming repeat sampling


    【解决方案1】:

    如果您没有指定调度程序(并且没有操作员设置调度程序),那么所有处理都发生在同一个线程上。 just(null).repeat() 将占用 100% 的 CPU 内核,因此没有其他机会继续进行。

    在您的情况下,interval 是在 Scedulers.computation() 调度程序上生成的,并且因为它在开始时没有发生调度程序更改,所以您的 repeat 也在同一个线程上工作。

    在第二种情况下,所有内容都在同一个线程上订阅,除了间隔,它在自己的调度程序上;剩下的就看sample的内部实现了。

    如果您使用特定的调度程序,它应该可以工作:

    .sample(Observable.just(null).repeat().subscribeOn(Schedulers.computation()))
    

    请注意,如果您只想使用空值而不是 interval 生成的数字,更有效的方法是使用 map 而不是 sample

    .map(any -> (Object) null)
    

    【讨论】:

    • 哦哦哦,这很有意义。我忘记了间隔默认设置为不同的调度程序。天哪!
    • 看起来repeat也可以将调度器作为参数! repeat(Schedulers.computation())
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多