05-超越回调
Vert.x 异步编程模型精要
5.1 回调的局限性
核心问题:
回调嵌套导致代码可读性差(回调地狱),错误处理分散。
功能代码与异步协调代码纠缠在一起。
Vert.x优化:
通过链式回调(如handler1(result -> handler2(...))
)缓解问题,但复杂逻辑仍难维护。
5.2 Futures & Promises(推荐基础方案)
核心概念
Promise
:写入最终结果(成功/失败)。Future
:读取结果,支持链式操作(map
、flatMap
、recover
)。
Vert.x 4+ 支持
- 核心 API 提供返回
Future
的方法(如httpServer.listen()
)。 - 与 JDK
CompletionStage
互操作,无缝对接JDK异步API(如Future.fromCompletionStage()
)。 - 组合操作:
CompositeFuture.all()
并行等待多个Future完成。
适用场景:
- 简单异步操作链式调用。
- 需要与 Java 标准库(如
CompletableFuture
)交互时。
5.3 反应式扩展(RxJava)
适用场景:
复杂事件流处理(如合并多传感器数据)。
核心类型:
Observable
:无背压的事件流(适合GUI事件)。Flowable
:支持背压(推荐用于网络I/O)。
操作符:
zip
:合并多个流结果(类似CompletableFuture.allOf
)。flatMap
:扁平化嵌套流(避免回调地狱)。retryWhen
:错误重试策略。
Vert.x集成:
- 使用
vertx-rx-java2
模块,API自动适配(如webClient.rxGet()
返回Single<HttpResponse>
)。
5.4 Kotlin协程(语言级优雅方案)
核心优势:
将异步代码写成同步风格,避免回调嵌套。
关键概念
suspend
函数:标记可挂起的异步操作(如delay(100)
)。CoroutineScope
:管理协程生命周期(避免泄露)。
Vert.x集成
- 使用
CoroutineVerticle
作为基类,直接在start()
中编写协程。
class MyVerticle : CoroutineVerticle() {
override suspend fun start() {
val temp1 = webClient.get("/temp1").await()
val temp2 = webClient.get("/temp2").await()
// 组合结果并发送
}
}
5.5 模型选择
场景 | 推荐模型 | 说明 |
---|---|---|
回调 | 适用于 简单异步操作 优点:简单直接,无需额外依赖 缺点:嵌套导致代码混乱 | |
简单异步操作组合 | Futures/Promises | Vert.x原生支持,代码简洁(如future.compose() )。 |
复杂事件流处理 | RxJava | 丰富的操作符(filter 、reduce ),支持背压(Flowable )。 |
代码可读性优先 | Kotlin协程 | 代码结构接近同步风格,适合Kotlin项目(如lifecycleScope.launch )。 |
混合使用 | 多模型共存 | Vert.x允许同一项目混用不同模型(如RxJava处理流,协程处理业务逻辑)。 |
5.6 总结
- 回调是基础,但需避免嵌套。
- Futures 简化链式调用,适合简单场景。
- RxJava 擅长复杂事件流,操作符丰富。
- Kotlin 协程 以同步写异步,提升可读性。