blockingForEach(),为什么将函数应用于阻塞的可观察对象

时间:2018-06-21 19:11:41

标签: multithreading rx-java observable reactivex

我无法理解可观察对象(尤其是blockingForEach()

)的含义

将函数应用到我们永远不会看到的观察点有什么意义?在下面,我尝试按照以下顺序输出控制台

this is the integer multiplied by two:2
this is the integer multiplied by two:4
this is the integer multiplied by two:6
Statement comes after multiplication

我当前的方法在乘法之前打印语句

 fun rxTest(){
    val observer1  = Observable.just(1,2,3).observeOn(AndroidSchedulers.mainThread())

    val observer2 = observer1.map { response -> response * 2 }


    observer2
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe{ it -> System.out.println("this is the integer multiplie by two:" + it) }

    System.out.println("Statement comes after multiplication ")
}

现在,我已将方法更改为包含blockingForEach()

 fun rxTest(){
    val observer1  = Observable.just(1,2,3).observeOn(AndroidSchedulers.mainThread())

    val observer2 = observer1.map { response -> response * 2 }


    observer2
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(AndroidSchedulers.mainThread())
            .blockingForEach { it -> System.out.println("this is the integer multiplie by two:" + it) }

    System.out.println("Statement comes after multiplication ")
}

1。)一旦不再阻塞,转换后的可观察物会发生什么?那是不必要的工作,因为我们从来没有看到过这些可观察对象吗?

2。)为什么在我进行订阅时,我的System.out(“ Statement ...)为什么出现在我的可观察对象之前?它像observable2一样跳过其阻塞方法,进行System.out调用,然后恢复其订阅< / p>

1 个答案:

答案 0 :(得分:1)

目前尚不清楚您所说的“永远不会看到”观察者链发出的值的意思。观察者链中发出的每个值都由发出它们的点下游的观察者看到。在您订阅观察者链的那一刻,通常是发生副作用的地方,例如打印值或将其存储到变量中。因此,总是可以看到这些值。

在您的示例中,您对调度程序的工作方式感到困惑。当您使用observeOn()subscribeOn()运算符时,您是在告诉观察者链在之后发出值,然后将该值移到另一个线程上。在线程之间移动数据时,目标线程必须能够处理数据。如果您的主代码在同一线程上运行,则可以将自己锁定在外,否则将对操作进行重新排序。

通常,强烈建议不要使用阻塞操作。测试时通常可以使用阻塞操作,因为您可以完全控制后果。在其他几种情况下,阻塞可能很有意义。一个示例是需要访问数据库或其他资源的应用程序。如果没有该资源,该应用程序将毫无用处,因此它将阻塞直到它变得可用或发生超时,然后将其踢出去。