深入分析Vert.x里Future的compose() 和 map()

news2024/11/24 21:01:45

Vert.x 是一个异步框架。因此,它需要一种方法来表示可能尚未准备好但将来可用的值,也称为延迟值(deferred values)。您可能熟悉不同名称的延迟值:Promise, Future, Deferred, Mono, Uni 都是延迟值设计模式的实现。

Vert.x 有自己的延迟值实现,简称为 Future ,是Vert.x的核心概念之一。不过,这不应该与Java的 Future 混淆。Vert.x的Future实现是完全独立的。

💡提示: 尽管 Vert.x Future 可以使用 toCompletionStage() 方法转换为 Java的 Future

Vert.x Future 有两个描述非常相似且可能会让您感到困惑的方法: composemap

我想深入研究它们中的每一个是如何工作的,以及何时应该使用它们。

让我们从最简单的场景开始,看看一个完整的future:

Future<String> f = Future.succeededFuture("a");

此处, f 表示已成功计算的延迟值。

现在,让我们看看 compose()map() 方法在延迟值上的行为,如果我们向它们传递一个简单的函数:给定 X,返回 X

Future<String> composeResult = f.compose(a -> Future.succeededFuture(a));

Future<String> mapResult = f.map(a -> a);

虽然 map() 允许我们按原样返回值,但 compose() 强制我们将结果包装在新的 Future 中。这是因为 map() 可以返回任何类型的结果,而 compose() 必须返回某种 Future

乍一看,compose() 似乎没有明显的好处。 两种方法都接收String类型的值,但要返回普通的结果,compose()需要一个额外的步骤。

但在我们完全放弃 compose() 方法之前,让我们看看另一个场景:

Future<Future<String>> f = Future.succeededFuture(Future.succeededFuture("a"));

在这里,我们将 Future 包装在另一个 Future 中。这个例子乍一看似乎有些牵强,但稍后我将向您展示这种嵌套在异步框架中非常常见。

当我们尝试在这个嵌套的 Future 上调用 map()compose() 时会发生什么?

Future<String> composeResult = f.compose(a -> a);

Future<String> mapResult = f.map(a -> a.result());

虽然以前的 compose() 代码更复杂,但现在是 map() 代码需要执行一些额外的工作。
To unnest the Future using map(), we need to invoke the result() method. With composeResult, though, the value is readily accessible. That’s because compose flattens the Future for us.
要使用 map() 取消嵌套 Future ,我们需要调用 result() 方法。但是,使用 composeResult ,该值很容易访问。那是因为compose 为我们扁平化了 Future

💡提示: 出于同样的原因,在 Vert.x 中 flatMap() 只是 compose() 的别名。

因此,无论何时使用 Futures,compose() 实际上都是比 map() 更好的处理方式。
另一种查看方式是比较我们将identity function传递给两种方法时的结果:

Future<String> composeResult = f.compose(a -> a);

Future<Future<String>> mapResult = f.map(a -> a);

可视化此处发生的情况可能很有用:
在这里插入图片描述
注意颜色。 仅根据结果类型判断,您可以假设 compose() 将返回嵌套的 Future,而 map 将返回它接收到的相同对象。 这是不正确的。 compose()map() 都返回一个新的 Future
但是 compose 将实际值包装成一个Future,而 map 将底层的Future包装成一个新值。
我之前承诺过,我将演示在真实的 Vert.x 代码中可以在何处进行Future嵌套。 让我们看一下官方文档中的以下稍微简化的示例:

var future = client
        .request(HttpMethod.GET, "some-uri")
        .map(request -> request.send()
                .map(response -> response
                        .body()
                        .map(buffer -> buffer.toJsonObject())));

此代码使用标准 Vert.x HttpClient 发送请求,然后读取响应正文并将其解析为 JSON。我相信你已经写了数百次类似的代码。

问题是,这里的结果是什么类型?

让我们明确类型:

Future<Future<Future<JsonObject>>> future = client
                .request(HttpMethod.GET, "some-uri")
                .map(request -> request.send()
                        .map(response -> response
                                .body()
                                .map(buffer -> buffer.toJsonObject())));

因为我们使用了 map() ,所以没有取消嵌套。 因此,为了读取 JSON,我们需要手动取消嵌套:

var json = future.result().result().result();

现在让我们用 compose() 替换 map() ,保持结果类型明确:

Future<JsonObject> future = client
                .request(HttpMethod.GET, "some-uri")
                .compose(request -> request.send()
                        .compose(response -> response
                                .body()
                                .map(buffer -> buffer.toJsonObject())));

结果类型现在很浅,并且易于使用:

var json = future.result();

请注意,最后一个方法仍然是 map() 。这是因为 body() 方法返回的是 Buffer 对象,而不是 Future ,因此无需平展它。

总结: 当 lambda 的参数为 Future 时,请使用 compose() 。当它是一个简单的对象时,请使用 map()


原文链接: https://alexey-soshin.medium.com/understanding-vert-x-compose-vs-map-d464dee78980

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IP 地址类型有哪些?

IP 地址有不同的类别&#xff0c;每个类别内有不同的类型。消费者 IP 地址具有互联网服务计划的每个个人或企业都将拥有两种类型的 IP 地址&#xff1a;专用 IP 地址和公共 IP 地址。术语“公共”和“专用”与网络位置有关 - 即&#xff0c;在网络内部使用专用 IP 地址&#xf…

【C++】30h速成C++从入门到精通(内存管理、函数/类模板)

C内存分布我们先来看一下下面的一段代码相关问题int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (int*)mal…

离线数据仓库项目搭建——准备篇

文章目录&#xff08;一&#xff09;什么是数据仓库&#xff08;二&#xff09;数据仓库基础知识&#xff08;三&#xff09;数据仓库建模方式&#xff08;1&#xff09;星行模型&#xff08;2&#xff09;雪花模型&#xff08;3&#xff09;星型模型 VS 雪花模型&#xff08;四…

【iobit 软件】家族系列 - 正版激活码

装机必备iobit系列软件 - 激活码获取看最后 第一款、Advanced SystemCare 16 您需要的人工智能驱动的PC优化器&#xff0c;以释放磁盘空间&#xff0c;加速PC并保护在线隐私。 功能特点&#xff1a; 1. 系统清理与优化&#xff1a;通过清除系统垃圾文件、注册表信息、无用文…

智能微型断路器在某银行网点的设计与应用

安科瑞 耿敏花【摘要】&#xff1a;随着人工智能、移动互联等现代信息技术和通信技术在电力行业的应用&#xff0c;实现电力系统各个环节人机交互、万物互联&#xff0c;打造状态全方面感知、信息合理处理、应用便捷灵活的泛在电力物联网已成为必然趋势 。本文主要对智能微型断…

后羿采集器快速入门----一款没有编程经验也能轻松使用的数据采集软件

后羿采集器快速入门 一、前言 不知道大家有没有苦恼于如何快速获取网页上的数据&#xff1f;想要进行大量重复性的操作但又要花费大量时间经历学习爬虫&#xff0c;这对于没啥编程基础的朋友们来说简直太不友好了&#xff01;那么有没有一个软件&#xff0c;能够通过傻白甜式…

【设计模式】代理模式

代理模式 为某个对象提供一种代理&#xff0c;以控制其他对象对这个对象的访问。属于结构型模式。 某些情况下&#xff0c;一个对象A不适合或者不能引用、直接访问某个对象B&#xff0c;而代理对象可以在客户端A和目标对象B之间起到中介作用 代理模式主要有三个重要角色: 抽…

【推拉框-手风琴】vue3实现手风琴效果的组件

简言 在工作时有时会用到竖形手风琴效果的组件。 在此记录下实现代码和实现思路。 手风琴实现 结构搭建 搭建结构主要实现盒子间的排列效果。 用flex布局或者其他布局方式将内容在一行排列把每一项的内容和项头用盒子包裹&#xff0c; 内容就是这一项要展示的内容&#xf…

python16行代码获取原神全角色+全语音

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 本来是不玩原神的&#xff0c;但是实在是经不住双重诱惑呀~ 毕竟谁能拒绝角色风景超级好看又可以爬树、炸鱼、壶里造房子、抓小动物、躲猫猫的游戏捏~ 今天点进官网~角色得配音让我沉陷其中&#xff0c;于是 我决定把他们爬…

数据库可视化开发工具内容介绍

在现代化办公环境中&#xff0c;数据管理的重要性不言而喻。对于企业来说&#xff0c;将企业内部的数据做好规划和管理&#xff0c;可以给企业提升办公协作效率&#xff0c;为企业高层做出正确的经营决策奠定基础。本文主要给大家介绍的是数据化可视化开发工具的内容&#xff0…

狂神Springmvc,404,500错误解决办法(灵)

b站狂神springmvc404&#xff0c;500解决办法 首先校验各个文件是否正确 配置web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSche…

HLS协议有哪些特别优势

阿酷TONY / 2023-3-3 / 长沙 可以实现码率的动态自适应&#xff0c;清晰度动态成为可能&#xff1b;HLS是基于HTTP 协议的&#xff0c;更易于做各平台的适配与兼容&#xff1b;多终端跨平台的支持性&#xff1a; PC端, Android端, IOS 平台&#xff0c;微信之类的都支持&am…

C++中邻接矩阵、邻接表、链式前向星具体用法及讲解

图论在提高组中几乎占据半壁江山&#xff0c;而今天要讲的就是如何存储一个图一.邻接矩阵原理要建立一个图&#xff0c;根本的要素就是边和点而想要让计算机存储边和点就需要用到一些数据结构邻接矩阵是最简单的他使用了一个二维数组&#xff0c;来表示一个图假设数组名为map那…

彻底搞清楚内存泄漏的原因,如何避免内存泄漏,如何定位内存泄漏

作为C/C开发人员&#xff0c;内存泄漏是最容易遇到的问题之一&#xff0c;这是由C/C语言的特性引起的。C/C语言与其他语言不同&#xff0c;需要开发者去申请和释放内存&#xff0c;即需要开发者去管理内存&#xff0c;如果内存使用不当&#xff0c;就容易造成段错误(segment fa…

Spark Streaming DStream转换

DStream上的操作与RDD的类似&#xff0c;分为Transformations&#xff08;转换&#xff09;和Output Operations&#xff08;输出&#xff09;两种&#xff0c;此外转换操作中还有一些比较特殊的算子&#xff0c;如&#xff1a;updateStateByKey()、transform()以及各种Window相…

打造优秀项目团队的3个核心原则

优秀的项目团队必须是高绩效的&#xff0c;而打造这样优秀团队需要3个核心原则&#xff1a;共同的目标、专业的技能和高效的协作。 1、共同的项目目标 项目团队的共同目标就是实现项目的交付成果。项目经理以远景宏大的方式将目标传递给团队成员&#xff0c;以激发团队成员的战…

jeesite多环境配置

jeesite多环境配置 参考网址&#xff1a; https://blog.csdn.net/shaoming314/article/details/129115912?spm1001.2014.3001.5501 开源项目地址&#xff1a; https://gitee.com/thinkgem/jeesite Spring Spring MVC mybatis Ehcache shiro mysql jsp (主要技术栈) 项目…

【大数据离线开发】8.3 Hive的数据模型

8.4 Hive的数据模型 Hive的数据存储 基于HDFS没有专门的数据存储格式存储结构主要包括&#xff1a;数据库、文件、表、视图可以直接加载文本文件&#xff08;.txt文件&#xff09;创建表时&#xff0c;指定Hive数据的列分隔符与行分隔符 8.4.1 内部表 hive 的内部表类似 My…

hexo静态网站部署到腾讯云cos

hexo支持很多部署方案&#xff0c;最直接的就是部署在GitHub Pages服务上&#xff0c;国内gitee、coding等代码托管平台也都支持静态网站服务&#xff0c;而且免费。 但是GitHub在国内访问不太稳定&#xff0c;国内的代码托管平台资源和服务也不太稳定&#xff0c;后来想了想&…

windows安装tomcat

这里写自定义目录标题tomcat官网下载安装包并解压环境变量配置启动tomcat访问http://localhost:8080/修复启动出现乱码问题tomcat官网下载安装包并解压 环境变量配置 系统环境变量新增&#xff1a; 变量名&#xff1a;CATALINA_HOME 变量值&#xff1a;tomcat的安装目录 编辑…