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
map vs flatMap in 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_ROOT
on the server.
我有文件 (a Flux<FilePart>
),我想将其复制到UPLOAD_ROOT
服务器上的某些文件。
This example is taken from a book.
这个例子取自一本书。
I can change all the .map
to .flatMap
and vice versa and everything still works. I wonder what the difference is.
我可以将所有更改.map
为.flatMap
,反之亦然,一切仍然有效。我想知道有什么区别。
回答by Simon Baslé
map
is for synchronous, non-blocking, 1-to-1 transformationsflatMap
is for asynchronous (non-blocking) 1-to-N transformations
map
用于同步、非阻塞、1 对 1 转换flatMap
用于异步(非阻塞)1 到 N 转换
The difference is visible in the method signature:
差异在方法签名中可见:
map
takes aFunction<T, U>
and returns aFlux<U>
flatMap
takes aFunction<T, Publisher<V>>
and returns aFlux<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, flatMap
expects 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>
: flatMap
will flatten each inner Publisher<V>
into the output sequence of allthe V
s.
另一方面,对于每个 都flatMap
期望一个。它知道如何处理它:订阅它并在输出序列中传播它的元素。其结果,返回类型:将压扁每个内进入的输出序列的所有的第Publisher<V>
T
Flux<V>
flatMap
Publisher<V>
V
About the 1-N aspect:
关于1-N方面:
for each <T>
input element, flatMap
maps 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 Publisher
can emit multiple elements, and flatMap
works 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 map
really 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 Flux
is still asynchronous as a whole. If it blocks mid-sequence, it will impact the rest of the Flux
processing, or even other Flux
.
是的:它在操作符应用它的方式上是同步的(一个简单的方法调用,然后操作符发出结果)并且是非阻塞的,因为函数本身不应该阻塞调用它的操作符。换句话说,它不应该引入延迟。那是因为Flux
a 整体上仍然是异步的。如果它阻塞中间序列,它将影响其余的Flux
处理,甚至其他Flux
.
If your map function is blocking/introduces latency but cannot be converted to return a Publisher
, consider publishOn
/subscribeOn
to offset that blocking work on a separate thread.
如果您的 map 函数阻塞/引入延迟但无法转换为返回 a Publisher
,请考虑publishOn
/subscribeOn
以抵消单独线程上的阻塞工作。