繁体   English   中英

Spring WebFlux (Reactor) 结合多种非阻塞方法

[英]Spring WebFlux (Reactor) combine multiple non-blocking methods

使用非阻塞调用我想一般采用 Mono 并调用一个返回 Flux 的方法,对于 Flux 中的每个项目,调用一个返回 Mono 的方法以返回一个 Flux,它是 Bar + Foo + Bar 的聚合 object并且具有与 Flux 方法返回(将返回)一样多的元素。

作为一个具体的例子: 方法:

Flux<Bar> getBarsByFoo(Foo foo);
Mono<More> getMoreByBar(Bar bar);
Combined getCombinedFrom(Bar bar, Foo foo, More more);

工作代码部分:

Flux<Combined> getCombinedByFoo(Foo foo) {
  getBarsByFoo(foo)... 
}

从阻塞的角度来看,我想要完成的是:

List<Combined> getCombinedByFoo(Foo foo) {
  List<Bar> bars = getBarsByFoo(foo):
  List<Combined> combinedList = new ArrayList<>(bars.size());
  for (Bar bar: bars) {
    More more = getMoreByBar(bar);
    combinedList.append(getCombinedFrom(bar, foo, more));
  }
  return combinedList;
}

任何有关使用 Flux 和 Mono 方法的帮助将不胜感激。 我仍在学习将我的大脑转变为非阻塞思维。 从概念上讲,我认为有一个 function 可以应用于从 getBarsByFoo(Foo foo) 到组合元素的 map 中的每个元素(Bar)......

是这样的:

Flux<Combined> getCombinedByFoo(Foo foo) {
    return getBarsByFoo(foo)
            .flatMap(bar -> getMoreByBar(bar)
                .flatMap(more -> getCombinedFrom(bar, foo, more)))
}

我不知道要检查,我是徒手写的,但我猜是这样的。

我喜欢将 Reactor 编程视为操作流(如在流编程中),作为操作链/DAG。

在您的情况下,您想:

  1. map每个发出 Bar object 到 Combined object。
  2. 在此过程中,您需要使用/调用另一个发布者来获取其他信息:
    • 您需要等待它完成,以便获取其 output 值。 对于 Monads/streams,有一个flatMap操作。
    • flatMap等待(或者你可以说它提取)一个不同的发布者值来将它集成到当前的操作链中。 我认为它被称为 flatMap 是因为从某种意义上说,我们打破了层次结构以将两个嵌套的发布者/monad扁平化为一个合并的发布者/monad。

以下示例显示了您的方法的反应式版本(对于不太详细的版本,请参阅Toerktumlare 回答

Flux<Combined> combine(Foo foo) {
    Flux<Bar> bars = getBarBy(foo);
    Flux<Combined> result = bars.flatMap(bar -> {
        Mono<More> nextMore = getMoreBy(bar);
        Mono<Combined> next = nextMore.map(more -> getCombinedFrom(foo, bar, more));
        return next;
    );
    return result;
}

如果你通过 Mono 得到你的 foo object,你可以在上面调用flatMapMany

Mono<Foo> nextFoo = ...;

Flux<Combined> = nextFoo.flatMapMany(foo -> combine(foo));

警告

flatMap非常强大:它可以触发提供的操作的并发执行。 在您的情况下,这意味着可以同时启动许多getMoreBy(bar)操作。 但它是一把双刃剑,因为这意味着:

  • 元素的顺序没有保留(或者至少不能保证)
  • 在资源受限的系统中,同时启动多个操作可能会损害性能或对系统造成损害(例如,打开太多文件等)

默认情况下并发行为非常高 (256) 并且可以通过不同的方式进行控制:

  1. flatMap 接受一个可选的并发参数,以调整允许同时运行的任务数。
  2. 还有其他运算符可以扁平化发布者,但管理工作的方式不同,例如concatMap :它强制执行映射任务的顺序执行(因此保持顺序)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM