java 反应堆中的地图与平面地图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49115135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 10:16:37  来源:igfitidea点击:

map vs flatMap in reactor

javaproject-reactor

提问by shredding

I've found a lot of answers regarding RxJava, but I want to understand how it works in Reactor.

我找到了很多关于RxJava的答案,但我想了解它在 Reactor 中的工作原理。

My current understanding is very vague, i tend to think of map as being synchronous and flatMap to be asynchronous but I can't really get my had around it.

我目前的理解非常模糊,我倾向于认为 map 是同步的,而 flatMap 是异步的,但我无法真正理解它。

Here is an example:

下面是一个例子:

files.flatMap { it ->
    Mono.just(Paths.get(UPLOAD_ROOT, it.filename()).toFile())
        .map {destFile ->
            destFile.createNewFile()
            destFile    
        }               
        .flatMap(it::transferTo)
}.then()  

I have files (a Flux<FilePart>) and i want to copy it to some UPLOAD_ROOTon the server.

我有文件 (a Flux<FilePart>),我想将其复制到UPLOAD_ROOT服务器上的某些文件。

This example is taken from a book.

这个例子取自一本书。

I can change all the .mapto .flatMapand vice versa and everything still works. I wonder what the difference is.

我可以将所有更改.map.flatMap,反之亦然,一切仍然有效。我想知道有什么区别。

回答by Simon Baslé

  • mapis for synchronous, non-blocking, 1-to-1 transformations
  • flatMapis for asynchronous (non-blocking) 1-to-N transformations
  • map用于同步、非阻塞、1 对 1 转换
  • flatMap用于异步(非阻塞)1 到 N 转换

The difference is visible in the method signature:

差异在方法签名中可见:

  • maptakes a Function<T, U>and returns a Flux<U>
  • flatMaptakes a Function<T, Publisher<V>>and returns a Flux<V>
  • map接受一个Function<T, U>并返回一个Flux<U>
  • flatMap接受一个Function<T, Publisher<V>>并返回一个Flux<V>

That's the major hint: you canpass a Function<T, Publisher<V>>to a map, but it wouldn't know what to do with the Publishers, and that would result in a Flux<Publisher<V>>, a sequence of inert publishers.

这是主要提示:您可以将 a 传递Function<T, Publisher<V>>给 a map,但它不知道如何处理Publishers,这将导致 a Flux<Publisher<V>>,一系列惰性发布者。

On the other hand, flatMapexpects a Publisher<V>for each T. It knows what to do with it: subscribe to it and propagate its elements in the output sequence. As a result, the return type is Flux<V>: flatMapwill flatten each inner Publisher<V>into the output sequence of allthe Vs.

另一方面,对于每个 都flatMap期望一个。它知道如何处理它:订阅它并在输出序列中传播它的元素。其结果,返回类型:将压扁每个内进入的输出序列的所有的第Publisher<V>TFlux<V>flatMapPublisher<V>V

About the 1-N aspect:

关于1-N方面:

for each <T>input element, flatMapmaps it to a Publisher<V>. In some cases (eg. an HTTP request), that publisher will emit only one item, in which case we're pretty close to an async map.

对于每个<T>输入元素,flatMap将其映射到Publisher<V>. 在某些情况下(例如 HTTP 请求),该发布者只会发出一项,在这种情况下,我们非常接近 async map

But that's the degenerate case. The generic case is that a Publishercan emit multiple elements, and flatMapworks just as well.

但那是退化的情况。一般情况是 aPublisher可以发出多个元素,并且也能flatMap正常工作。

For an example, imagine you have a reactive database and you flatMap from a sequence of user IDs, with a request that returns a user's set of Badge. You end up with a single Flux<Badge>of all the badges of all these users.

举个例子,假设你有一个反应式数据库,你从一系列用户 ID 中进行 flatMap,请求返回用户的Badge. 您最终会Flux<Badge>获得所有这些用户的所有徽章中的一个。

Is mapreally synchronous and non-blocking?

map真的是同步和非阻塞的吗?

Yes: it is synchronous in the way the operator applies it (a simple method call, and then the operator emits the result) and non-blocking in the sense that the function itself shouldn't block the operator calling it. In other terms it shouldn't introduce latency. That's because a Fluxis still asynchronous as a whole. If it blocks mid-sequence, it will impact the rest of the Fluxprocessing, or even other Flux.

是的:它在操作符应用它的方式上是同步的(一个简单的方法调用,然后操作符发出结果)并且是非阻塞的,因为函数本身不应该阻塞调用它的操作符。换句话说,它不应该引入延迟。那是因为Fluxa 整体上仍然是异步的。如果它阻塞中间序列,它将影响其余的Flux处理,甚至其他Flux.

If your map function is blocking/introduces latency but cannot be converted to return a Publisher, consider publishOn/subscribeOnto offset that blocking work on a separate thread.

如果您的 map 函数阻塞/引入延迟但无法转换为返回 a Publisher,请考虑publishOn/subscribeOn以抵消单独线程上的阻塞工作。