当前位置: 首页 > 知识库问答 >
问题:

地图vs平面地图在Reactor

米项禹
2023-03-14

我已经找到了很多关于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()  

我有文件(aFlux

这个例子摘自一本书。

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


共有2个答案

洪浩
2023-03-14

flatMap方法类似于map方法,关键区别在于您提供给它的供应商应该返回Mono

使用map方法会产生一个Mono

例如,当你必须进行网络调用来检索数据时,它很有用,使用返回Mono的java API,然后进行另一个需要第一个结果的网络调用。

// Signature of the HttpClient.get method
Mono<JsonObject> get(String url);

// The two urls to call
String firstUserUrl = "my-api/first-user";
String userDetailsUrl = "my-api/users/details/"; // needs the id at the end

// Example with map
Mono<Mono<JsonObject>> result = HttpClient.get(firstUserUrl).
  map(user -> HttpClient.get(userDetailsUrl + user.getId()));
// This results with a Mono<Mono<...>> because HttpClient.get(...)
// returns a Mono

// Same example with flatMap
Mono<JsonObject> bestResult = HttpClient.get(firstUserUrl).
  flatMap(user -> HttpClient.get(userDetailsUrl + user.getId()));
// Now the result has the type we expected

此外,它允许精确地处理错误:

public UserApi {
  
  private HttpClient httpClient;
    
  Mono<User> findUser(String username) {
    String queryUrl = "http://my-api-address/users/" + username;
    
    return Mono.fromCallable(() -> httpClient.get(queryUrl)).
      flatMap(response -> {
        if (response.statusCode == 404) return Mono.error(new NotFoundException("User " + username + " not found"));
        else if (response.statusCode == 500) return Mono.error(new InternalServerErrorException());
        else if (response.statusCode != 200) return Mono.error(new Exception("Unknown error calling my-api"));
        return Mono.just(response.data);
      });
  }
                                           
}

夏侯阳
2023-03-14
  • map用于同步,非阻塞,1对1转换
  • 用于异步(非阻塞)1-N转换

在方法签名中可以看到差异:

  • map采用函数

这是主要的提示:您可以传递一个Function

另一方面,flatMap需要一个发布者

关于1-N方面:

对于每个

但这是堕落的情况。一般情况是,一个Publisher可以发出多个元素,而flatMap也同样有效。

例如,假设您有一个反应式数据库,您从一系列用户ID进行平面映射,请求返回一组用户的徽章。你最终会得到一个通量

map是否真的同步且无阻塞?

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

如果您的MAP函数阻塞/引入延迟,但不能转换为返回<代码>发布者< /代码>,请考虑<代码> PublySoo> <代码> />代码>订阅代码< /代码>,以在单独的线程上偏移该阻塞工作。

 类似资料:
  • 在闪光灯下,平面图也可以发出一条记录。似乎平面图可以代替地图。有人能告诉我这种情况下的区别吗?谢谢你。

  • 问题内容: 我目前的理解非常模糊,我倾向于认为map是同步的,而flatMap是异步的,但是我真的无法解决它。 这是一个例子: 我有文件(a ),我想将其复制到服务器上的某些文件中。 本示例摘自一本书。 我可以将所有更改为to ,反之亦然,一切仍然正常。我不知道有什么区别。 问题答案: 用于同步,非阻塞,一对一转换 用于异步(非阻塞)1-to-N转换 区别在方法签名中可见: 取a 并返回a 取a

  • 我使用的是Flink 0.10.0数据流。这是我的要求。 我的源系统是广播消息的自定义系统。在我的自定义SourceFunction实现中,我实现了回调来侦听消息。 每个回调都会得到不同类型的消息。 我想解码/转换在回调中收到的对象发送到我的SinkFunction。我相信我可以用FlatMapFunction或类似的软件来完成。 因为我有各种回调,所以我听每个回调的解码逻辑是不同的。我想不能有一

  • 我浏览了几篇文章,基本上都指出Hive用于结构化处理,Pig用于非结构化处理。我们什么时候需要本地地图缩减?你能指出一些使用Pig或Hive但在原生map Reduce中无法解决的场景吗?

  • 问题内容: 我想展平一个将键关联到的列表的a ,而不会丢失键映射。我很好奇,就好像它是可能的,与这样做有用的和。 我们从这样的东西开始: 假设mapFrom填充在某处,如下所示: 我们还假设列表中的值是唯一的。 现在,我想“展开”它以获得第二张地图,例如: 我可以这样做(或使用,非常类似): 现在,假设我要使用lambda而不是嵌套循环。我可能会做这样的事情: 我也尝试了,但是我不认为这是正确的方