Flux.create和Flux.generate之间的差异

时间:2018-04-20 23:56:54

标签: project-reactor

Flux.createFlux.generate之间有什么区别?我正在寻找 - 理想情况下使用一个示例用例 - 来了解何时应该使用其中一个。

2 个答案:

答案 0 :(得分:10)

简而言之:

  在Flux::create执行时,

Flux::generate不会对应用状态的变化做出反应。

长版本

Flux::create

当您想要计算不受应用状态和管道(您的管道)状态影响的多个(0 ...无穷大)值时,您将使用它 ==在 Flux::create == 下游之后的操作链。

为什么呢?因为您发送到Flux::create的方法会继续计算元素(或没有)。 下游将确定它想要的元素数量(元素== 下一个信号),如果他无法跟上,那些已经发出的元素将被删除/缓冲在一些策略中(默认情况下,它们将被缓冲,直到下游要求更多)。

第一个也是最简单的用例是用于发出值,理论上,这些值可以汇总到一个集合中,然后只取每个元素并用它做一些事情:

Flux<String> articlesFlux = Flux.create((FluxSink<String> sink) -> {
    /* get all the latest article from a server and
       emit them one by one to downstream. */
    List<String> articals = getArticalsFromServer();
    articals.forEach(sink::next);
});

如您所见,Flux.create用于阻塞方法(getArticalsFromServer)与异步代码之间的交互。

我确定Flux.create还有其他用例。

Flux::generate

Flux.generate((SynchronousSink<Integer> synchronousSink) -> {
        synchronousSink.next(1);
    })
    .doOnNext(number -> System.out.println(number))
    .doOnNext(number -> System.out.println(number + 4))
    .subscribe();

输出将为1 5 1 5 1 5................forever

在您发送给Flux::generate的方法的每次调用中,synchronousSink只能发出:onSubscribe onNext? (onError | onComplete)?

这意味着Flux::generate计算并发出按需。你应该什么时候使用它?如果计算可能未使用 downstream 的元素太昂贵,或者您发出的事件受应用程序状态或管道状态的影响(您的管道 ==在 Flux::create == 下游之后来的操作链。)

例如,如果您正在构建torrent应用程序,那么您将实时接收数据块。您可以使用Flux::generate将任务(要下载的块)分配给多个线程,只有当某个线程询问时,您才会计算要在Flux::generate内部下载的块。所以你只会发出你没有的块。使用Flux::create的相同算法将失败,因为Flux::create将发出我们没有的所有块,如果某些块无法下载,那么我们就会遇到问题。因为Flux::createFlux::generate执行时View对应用状态的变化没有反应。

答案 1 :(得分:2)

创建

  • 接受Consumer<FluxSink<T>>
  • 每个订阅者仅调用一次消费
  • 消费者可以立即发出0..N个元素
  • 发布者不知道下游状态。因此,我们需要提供“溢出策略”作为附加参数
  • 我们可以获得 FluxSink 的引用,使用它可以在需要时使用多个线程继续发射元素。

生成:

  • 接受Consumer<SynchronousSink<T>>
  • 根据下游需求一次又一次地调用消费者
  • 消费者最多只能发出一个元素,并带有可选的完成/错误信号。
  • 发布者根据下游需求生成元素
  • 我们可以获得 SynchronousSink 的参考。但这可能并不真正有用,因为我们只能发出一个元素

选中此blog以获得更多详细信息。