java - react 堆中的 map 与平面 map

标签 java project-reactor

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

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

这是一个例子:

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

我有文件(一个Flux<FilePart>),我想把它复制到一些UPLOAD_ROOT在服务器上。

这个例子摘自一本书。

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

最佳答案

  • map用于同步、非阻塞、一对一的转换
  • flatMap用于异步(非阻塞)1 到 N 转换

差异在方法签名中可见:

  • map需要 Function<T, U>并返回 Flux<U>
  • flatMap需要 Function<T, Publisher<V>>并返回 Flux<V>

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

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

关于1-N方面:

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

但这是退化的情况。一般情况是 Publisher可以发出多个元素,并且 flatMap效果也一样。

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

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

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

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

关于java - react 堆中的 map 与平面 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49115135/

相关文章:

java - 无法通过 Dispatcher 访问 AEM/etc.clientlibs

java - neo4j执行结果: Extract multiple columns (since javaColumnAs only works once)

java - Spring Boot JPA 查询使用 isempty 和 isnull 关键字

java - 从 Android 到没有接入点的 Android 的消息

java - 将多个 Mono<List<Item>> 合并为一个

java - Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应

Android 上的 Java 并发

java - 如何在响应式(Reactive) Java 中将新对象添加到现有流中?

kotlin - 当时无法订阅

java - 使用 Lettuce 响应式(Reactive)命令订阅 Redis channel (pubsub)