【问题标题】:Reactor compose vs flatMapReactor compose vs flatMap
【发布时间】:2018-07-07 04:55:00
【问题描述】:

我继续使用 Reactor,现在我看到 compose 运算符的行为与 flatMap 完全一样,我想知道是否有什么我不明白的区别。

    @Test
public void compose() throws InterruptedException {
    Scheduler mainThread = Schedulers.single();
    Flux.just(("old element"))
            .compose(element ->
                    Flux.just("new element in new thread")
                            .subscribeOn(mainThread)
                            .doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName())))
            .doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName()))
            .subscribe(System.out::println);
    Thread.sleep(1000);
}

@Test
public void flatMapVsCompose() throws InterruptedException {
    Scheduler mainThread = Schedulers.single();
    Flux.just(("old element"))
            .flatMap(element ->
                    Flux.just("new element in new thread")
                            .subscribeOn(mainThread)
                            .doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName())))
            .doOnNext(value -> System.out.println("Thread:" + Thread.currentThread().getName()))
            .subscribe(System.out::println);
    Thread.sleep(1000);
}

这两个示例的行为并返回相同的结果。

问候。

【问题讨论】:

    标签: java spring project-reactor


    【解决方案1】:

    @Andrew 的解释非常好。只是想添加一个示例以更好地理解。

    Flux.just("1", "2")
            .compose( stringFlux -> {
                System.out.println("In compose"); // It takes whe whole Flux as input
               return stringFlux.collectList();
            }).subscribe(System.out::println);
    
    
    Flux.just("1", "2").flatMap(s -> { //Input to the anonymous function is individual items in stream
                System.out.println("In flatMap");
                return Flux.just(Integer.parseInt(s));
            }).subscribe(System.out::println);
    

    这会产生输出

    In compose
    [1, 2]
    In flatMap
    1
    In flatMap
    2
    

    这表示compose 适用于整个流,但flatMap 适用于流中的单个项目

    【讨论】:

      【解决方案2】:

      An excellent explanation by Dan Lew:

      不同之处在于compose() 是更高级别的抽象:它对整个流进行操作,而不是单独发出的项目。更具体地说:

      • compose() 是从流中获取原始Observable<T> 的唯一方法。因此,影响整个流的运算符(如subscribeOn()observeOn())需要使用compose()

        相反,如果您将subscribeOn()/observeOn() 放入flatMap(),它只会影响您在flatMap() 中创建的Observable,而不影响流的其余部分。

      • compose() 在您创建 Observable 流时立即执行,就像您已内联编写运算符一样。 flatMap() 在其 onNext() 被调用时执行,每次被调用。换句话说,flatMap() 转换每个项目,而compose() 转换整个流。

      • flatMap() 的效率必然较低,因为它必须在每次调用 onNext() 时创建一个新的 Observablecompose() 按原样在流上运行。如果您想用可重用代码替换某些运算符,请使用compose()flatMap() 有很多用途,但这不是其中之一。

      【讨论】:

      • 我更新了我的问题。我不明白为什么如果我执行这两个示例都在同一个线程中执行。我知道 sibscribeOn 它应该只影响 flatMap 内的 Flux
      • @paul, single() 返回一个默认的、共享的、单线程支持 Scheduler 实例
      • 对于所有类型的调度程序,我都会收到相同的结果。我不知道我在这里做错了什么。
      • 查看在另一个线程中将线程从 flatMap 中运行出来。并在同一个中作曲。不用担心,第二个响应现在是 100% 清楚的。谢谢!
      猜你喜欢
      • 2023-02-13
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多