【问题标题】:How to avoid repeating maping operations for similar subscribers in Sping Reactor?如何避免 Spring Reactor 中类似订阅者的重复映射操作?
【发布时间】:2021-01-24 23:51:24
【问题描述】:

我有一个发布字符串的发布者和许多可能使用相同映射函数来创建具有不同过滤器的模型的订阅者。

出版商:

val publisher: Flux<String> = ...

订阅者#1

val sub1 = publisher.map{veryExpensiveConverter.convert(it)}
                    .filter(it.metric<10)

订阅者#2

val sub2 = publisher.map{veryExpensiveConverter.convert(it)}
                    .filter(it.metric>5)

订阅者#3

val sub3 = sub2.map{cheapConverter.convert(it)}
                    .filter(it.metric>8)

订阅者#4

val sub4 = sub3.map{yetAnotherConverter.convert(it)}
                    .filter(it.metric>80)

最后我订阅了所有的助焊剂

Flux.merge(sub1, sub2, sub3, ..., subn)
     .map{//some logic for following data of subscribers}
     .subscribe()

问题:veryExpensiveConverter 针对每个订阅者的相同发布记录执行了多次。 执行流程看起来

Input1 -> veryExpensiveConverter -> filter1 -> output1
       -> veryExpensiveConverter -> filter2 -> output2
       -> veryExpensiveConverter -> cheapConverter -> filter3 -> output3

我也想要

Input1 -> veryExpensiveConverter -> filter1 -> output1  
                                 -> filter2 -> output2
                                 -> cheapConverter -> filter3 -> output3

什么模式最适合避免为每个订阅者执行相同的映射?

【问题讨论】:

    标签: spring kotlin reactive-programming project-reactor


    【解决方案1】:

    您可以在某种程度上.share() 以确保对该共享部分的每个订阅仅触发其上方的单个订阅。

    您还可以查看.publish().xxx() 方法以获得更高级的自动触发器(.share() 将在第一个订阅到来后立即开始其源代码)。

    类似这样的:

    val expensiveDoneOnce = publisher
        .map{veryExpensiveConverter.convert(it)}
        .publish()
        .refCount(2)
    val sub1 = expensiveDoneOnce.filter(it.metric < 10)
    val sub2 = expensiveDoneOnce.filter(it.metric > 5)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 2010-10-23
    • 1970-01-01
    相关资源
    最近更新 更多