首页 > 解决方案 > 官方(和丑陋的)顺序组合的替代品

问题描述

在 vertx 指南中,链接异步调用的顺序组合如下所示:

FileSystem fs = vertx.fileSystem();
Future<Void> startFuture = Future.future();

Future<Void> fut1 = Future.future();
fs.createFile("/foo", fut1.completer());

fut1.compose(v -> {
  // When the file is created (fut1), execute this:
  Future<Void> fut2 = Future.future();
  fs.writeFile("/foo", Buffer.buffer(), fut2.completer());
  return fut2;
}).compose(v -> {
          // When the file is written (fut2), execute this:
          fs.move("/foo", "/bar", startFuture.completer());
        },
        // mark startFuture it as failed if any step fails.
        startFuture);

是我自己还是这段代码真的很麻烦且难以阅读?

应该有另一种方法,而不会陷入回调地狱。很遗憾关于vertx的博客文章太少了,任何想法都非常感谢。

标签: javavert.x

解决方案


如今,用于在 JVM 上编写异步、非阻塞代码的事实上的库是RxJava。如果您不熟悉,我会说非常值得您花时间看一看,因为其中一个好处是能够将“流”编写为不像 JDK 的回调地狱般的组合Future流是。

幸运的是,Vert.x 与 RxJava 集成。例如,这是您使用 RxJava 工件重写的代码段:

@Override
public void start(Future<Void> startFuture) throws Exception {
    final FileSystem fs = vertx.fileSystem();

    fs.rxCreateFile("/foo")
        .andThen(fs.rxWriteFile("/foo", Buffer.buffer()))
        .andThen(fs.rxMove("/foo", "/bar"))
        .subscribe(
            () -> { 
                startFuture.complete(); 
            },
            error -> {
                startFuture.fail(error);
            }
        );
}

更加简洁易读。

笔记:

  • 使用 RxJava 2,因为它已经取代了 RxJava 1
  • ...然而,Vert.x 支持这两个版本,它们各自的工件位于不同的命名空间中:
    • io.vertx.rxjava对于版本 RxJava 1 工件
    • io.vertx.reactivex对于版本 RxJava 2 工件

希望有帮助!


推荐阅读