翻译: 白石(https://github.com/wjw465150/Vert.x-Core-Manual)

由于 Verticle start 方法的签名,你已经接触过 Vert.x 的futurespromises。 你可能也接触过其他语言,比如 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 接口定义了两种方法,onSuccessonFailure,用于处理值和错误。 当我们运行相应的代码时,我们会看到“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>。 然后,我们可以链接调用 onFailureonSuccess 来定义服务器启动或发生错误时要做什么。

Vert.x 4 异步编程 - Futures 和 Promises相关推荐

  1. Vert.x实战 异步数据和事件流

    本章包括: 为什么流[streams]是事件[eventing]之上的一个有用的抽象 什么是背压[back-pressure],为什么它是异步生产者和消费者的基础 如何从流[streams]中解析协议 ...

  2. 第一章: Vert.x 异步编程的基础知识

    第一章: Vert.x 异步编程的基础知识 翻译: 白石(https://github.com/wjw465150/Vert.x-Core-Manual) 构建反应式系统的第一步是采用异步编程.基于阻 ...

  3. Java 异步编程:从 Future 到 Loom

    众所周知,Java 开始方法执行到结束,都是由同一个线程完成的.这种方式虽易于开发调试,但容易因为锁.IO 等原因导致线程挂起,产生线程上下文切换.随着对应用并发能力要求越来越高,频繁的线程上下文切换 ...

  4. 笑了,面试官问我知不知道异步编程的Future。

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 荒腔走板 老规矩,先来一个简短的荒腔走板,给冰冷的技术文注 ...

  5. nodejs笔记-异步编程

    1.函数式编程 1.1高阶函数 函数参数只接受基本数据类型或者对象引用,返回值也是基本数据类型和对象引用. //常规参数传递和返回 function foo(x) {return x; } 复制代码 ...

  6. mysql 数据库引擎切花_asyncio异步编程【含视频教程】

    不知道你是否发现,身边聊异步的人越来越多了,比如:FastAPI.Tornado.Sanic.Django 3.aiohttp等. 听说异步如何如何牛逼?性能如何吊炸天....但他到底是咋回事呢? 本 ...

  7. Javascript异步编程的4种方法

    你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排 ...

  8. JavaScript 编程精解 中文第三版 十一、异步编程

    十一.异步编程 原文:Asynchronous Programming 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 孰能浊以澄?静之徐清: 孰能安以久?动之徐生. 老子,&l ...

  9. 在Java中异步编程,同事非要用rxJava,被我一顿吐槽!

    在Java中异步编程,不一定非要使用rxJava, Java本身的库中的CompletableFuture可以很好的应对大部分的场景. 这篇文章介绍 Java 8 的 CompletionStage ...

最新文章

  1. java核心技术面试精讲
  2. Zero Copy 简介
  3. 双机/RAC/Dataguard的区别【转】
  4. 表格合并行_合并行table表格
  5. rabbitmq 持久化_RabbitMQ原理与相关操作(三)消息持久化
  6. MySQL5.6 新特性之GTID【转】
  7. 如何写出让同事膜拜的漂亮代码?
  8. 物联网通信-期末复习
  9. photoshop柔光模式原理和案例教程
  10. SWUSTOJ #69 偷菜时间表
  11. 作为一名31岁的软件测试员,工作3年,月薪不到2W,担心被应届生取代
  12. 3D MAX 插件的基本知识和安装方法
  13. C++中cout后面输出时加endl和不加endl的区别
  14. GitLab允许开发人员推送到master分支
  15. 可配置组件库Fusion Design 了解一下
  16. 美容院没有顾客怎么办
  17. SSM项目的基本静态资源配置
  18. 【vue3 Api - watchEffect 的讲解 使用】- 侦听响应式数据执行副作用(effect)函数
  19. /Users/ng/Library/Developer/CoreSimulator/Devices/9B82D44F-703C-481E-BA28-71892DEA823D/data/Containe
  20. 蓝牙 - 苹果iOS所支持的profile

热门文章

  1. 《21世纪机器人》一一2.7 货物搬运工晨明号:重启前1小时
  2. IC设计行业分类辨析
  3. Spark SQL Guide——Data Sources
  4. 《公民的不服从》---梭罗(1) 英文翻译3
  5. 小程序:调用手机的相册
  6. Master of Both
  7. 时尚、时尚、最时尚,爱不释手是JAVA
  8. 快速查询圆通快递物流详情,并分析中转延误
  9. 为什么MATLAB用ar模型预测误差很大,关于AR模型预测的参数问题
  10. 童年旧事中,有我们对纯真岁月的无限留恋与缅怀