我应该如何使用Flux.publish()?

时间:2019-10-14 11:37:57

标签: spring-webflux project-reactor

我想在图像和报表中转换大量的数据。因为我想重用相同的数据源,所以我想到了在publish上使用Flux方法并连接结果,如下面的代码所示:

    @Test
    fun `inside a publish, I can concat multiple fluxes`() {
        data class Data(val d: String)
        data class Image(val i: String)
        data class Report(val r: String)

        val result = Flux.just(Data("some data"))
                .publish { fluxOfData ->
                    val fod = fluxOfData  //.cache()
                    val images = fod.flatMap { Flux.just(Image("my image")) }
                    val reports = fod.flatMap { Flux.just(Report("my report")) }

                    Flux.concat(images, reports)
                }
                .collectList()
                .block()

        Assertions.assertEquals(result, listOf(Image("my image"), Report("my report")))
    }

但是,上面的代码仅发送[Image(i=my image)],因此就像fluxOfData第一次被使用一样。但是,我希望我能够多次订阅fluxOfData

通过调用fluxOfData缓存fluxOfData.cache()时,结果如预期的那样。

那么Flux.publish()的用例是什么?
是否有另一种惯用的方式将数据转换为图像和报告?

1 个答案:

答案 0 :(得分:1)

publish()Flux变成热源(而不是冷源)。这意味着多个订阅者可以随时订阅并查看所有前进的元素,但是他们会错过所有事先发出的元素。

  

那么Flux.publish()的用例是什么?

有很多用例-也许是某种日志消息流以某种方式被消耗了(您只对实时弹出的日志消息感兴趣,而对以前的日志不感兴趣。)也许这是“直播”流,涵盖了一场体育比赛。也许是聊天室。

  

当通过调用fluxOfData.cache()来缓存fluxOfData时,结果如预期的那样出来。

是的,因为然后您将显式缓存所有发出的信号,因此,尽管它是热门来源,但仍可以重播流中所有现有元素的新订阅者。

  

还有另一种惯用的方式将数据转换为图像和报告吗?

考虑使用replay()而不是publish()

  

将此通量转换为热源,并缓存最后发出的信号以供其他订户使用。将保留无限量的onNext信号。完成和错误也将被重播。

从更一般的意义上讲,this也是很好的背景阅读。