Vert.x 4 异步编程 - Futures 和 Promises
翻译: 白石(https://github.com/wjw465150/Vert.x-Core-Manual)
由于 Verticle start
方法的签名,你已经接触过 Vert.x 的futures
和 promises
。 你可能也接触过其他语言,比如 JavaScript。 我们将进一步探索这个模型,看看它们是如何用 Vert.x 组合异步操作的有趣原语。
Vert.x 实现了与 Barbara Liskov 和 Liuba Shrira 的原始研究结果一致的 Future 和 Promise 模型。他们引入了 Promise 作为组合异步远程过程调用的语言抽象。
promise保存了一些现在还没有值的计算的值。承诺最终会带着一个结果值或一个错误完成。在异步I/O上下文中,promise自然适合保存异步操作的结果。反过来,future允许您读取最终将从promise中获得的值。
⚠重要: 总结一下:promise 用于写入最终值,future 用于在可用时读取它。 现在让我们看看它在 Vert.x 中是如何工作的。
5.3.1 Vert.x 中的 Futures 和 promises
Promise 是由一段即将执行异步操作的代码创建的。 例如,假设您要报告异步操作已完成,不是现在,而是在 5 秒内。 在 Vert.x 中,您将为此使用计时器,并使用 promise 来保存结果,如下面的清单所示。
清单 5.13 创建一个 promise
Promise<String> promise = Promise.promise();
vertx.setTimer(5000, id -> {if (System.currentTimeMillis() % 2L == 0L) {promise.complete("Ok!");} else {promise.fail(new RuntimeException("Bad luck..."));}
});// (...)
这里的异步操作是一个五秒的定时器,之后promise就完成了。 根据当前时间是奇数还是偶数,promise 以一个值完成或因异常而失败。 这很好,但我们如何真正从 Promise 中get
值?
想要在结果可用时做出反应的代码需要一个future对象。一个Vertx future是从一个promise创建的,然后传递给想要读取该值的代码,如下一个清单所示,即清单5.13的其余部分。
清单 5.14 从一个 Promise 中创建一个future
Future<String> future = promise.future();
return future;// (...)future.onSuccess(System.out::println).onFailure(err -> System.out.println(err.getMessage()));
Future
接口定义了两种方法,onSuccess
和 onFailure
,用于处理值和错误。 当我们运行相应的代码时,我们会看到“Ok!” 或“Bad lucky…”在5秒后打印。
我们可以使用Future执行更高级的异步操作,如下面的清单所示。
清单 5.15 高级future 组合操作
promise.future().recover(err -> Future.succeededFuture("Let's say it's ok!")).map(String::toUpperCase).flatMap(str -> {Promise<String> next = Promise.promise();vertx.setTimer(3000, id -> next.complete(">>> " + str));return next.future();}).onSuccess(System.out::println);
当 promise 失败时调用 recover
操作,它用于将错误替换为另一个值。 您可以将 recover
视为 Java 中的 catch
块的等价物,您可以在其中处理错误。 这里,我们只是使用一个成功的future提供一个恢复值,但是在更高级的情况下,当您无法进行恢复时,您也可以使用一个失败的future。
map 操作使用函数转换值,而 flatMap
与另一个异步操作组合。 您可以将flatMap
视为“然后”。 此处操作获取字符串值并在3秒后将“>>>”添加到其前面。 我们还看到了典型的 Promise/Future 模式,我们首先创建一个 Promise,然后执行一个最终完成 Promise 的异步操作,最后返回一个 Future,这样该值就可以被另一段代码使用。
5.3.2 Vert.x 4 中基于Future的 API
Vert.x 4 将 Future与回调一起引入核心 API。 虽然回调仍然是规范模型,但大多数 API 都可以使用返回Future
的变体。
这意味着给定一个方法,void doThis(Handler<AsyncResult<T>>)
,有一个形式为Future<T> doThis()
的变体。 下面的清单显示了一个很好的示例,我们在其中启动了一个 HTTP 服务器。
清单 5.16 使用Future方法启动 HTTP 服务器
@Override
public void start(Promise<Void> promise) {vertx.createHttpServer().requestHandler(this::handleRequest).listen(8080).onFailure(promise::fail).onSuccess(ok -> {System.out.println("http://localhost:8080/");promise.complete();});
}
我们在前面的例子中看到的 listen 方法接受一个回调接口Handler<AsyncResult<HttpServer>>
,但是在这里它返回一个 Future<HttpServer>
。 然后,我们可以链接调用 onFailure
和 onSuccess
来定义服务器启动或发生错误时要做什么。
Vert.x 4 异步编程 - Futures 和 Promises相关推荐
- Vert.x实战 异步数据和事件流
本章包括: 为什么流[streams]是事件[eventing]之上的一个有用的抽象 什么是背压[back-pressure],为什么它是异步生产者和消费者的基础 如何从流[streams]中解析协议 ...
- 第一章: Vert.x 异步编程的基础知识
第一章: Vert.x 异步编程的基础知识 翻译: 白石(https://github.com/wjw465150/Vert.x-Core-Manual) 构建反应式系统的第一步是采用异步编程.基于阻 ...
- Java 异步编程:从 Future 到 Loom
众所周知,Java 开始方法执行到结束,都是由同一个线程完成的.这种方式虽易于开发调试,但容易因为锁.IO 等原因导致线程挂起,产生线程上下文切换.随着对应用并发能力要求越来越高,频繁的线程上下文切换 ...
- 笑了,面试官问我知不知道异步编程的Future。
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 荒腔走板 老规矩,先来一个简短的荒腔走板,给冰冷的技术文注 ...
- nodejs笔记-异步编程
1.函数式编程 1.1高阶函数 函数参数只接受基本数据类型或者对象引用,返回值也是基本数据类型和对象引用. //常规参数传递和返回 function foo(x) {return x; } 复制代码 ...
- mysql 数据库引擎切花_asyncio异步编程【含视频教程】
不知道你是否发现,身边聊异步的人越来越多了,比如:FastAPI.Tornado.Sanic.Django 3.aiohttp等. 听说异步如何如何牛逼?性能如何吊炸天....但他到底是咋回事呢? 本 ...
- Javascript异步编程的4种方法
你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排 ...
- JavaScript 编程精解 中文第三版 十一、异步编程
十一.异步编程 原文:Asynchronous Programming 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 孰能浊以澄?静之徐清: 孰能安以久?动之徐生. 老子,&l ...
- 在Java中异步编程,同事非要用rxJava,被我一顿吐槽!
在Java中异步编程,不一定非要使用rxJava, Java本身的库中的CompletableFuture可以很好的应对大部分的场景. 这篇文章介绍 Java 8 的 CompletionStage ...
最新文章
- java核心技术面试精讲
- Zero Copy 简介
- 双机/RAC/Dataguard的区别【转】
- 表格合并行_合并行table表格
- rabbitmq 持久化_RabbitMQ原理与相关操作(三)消息持久化
- MySQL5.6 新特性之GTID【转】
- 如何写出让同事膜拜的漂亮代码?
- 物联网通信-期末复习
- photoshop柔光模式原理和案例教程
- SWUSTOJ #69 偷菜时间表
- 作为一名31岁的软件测试员,工作3年,月薪不到2W,担心被应届生取代
- 3D MAX 插件的基本知识和安装方法
- C++中cout后面输出时加endl和不加endl的区别
- GitLab允许开发人员推送到master分支
- 可配置组件库Fusion Design 了解一下
- 美容院没有顾客怎么办
- SSM项目的基本静态资源配置
- 【vue3 Api - watchEffect 的讲解 使用】- 侦听响应式数据执行副作用(effect)函数
- /Users/ng/Library/Developer/CoreSimulator/Devices/9B82D44F-703C-481E-BA28-71892DEA823D/data/Containe
- 蓝牙 - 苹果iOS所支持的profile
热门文章