如何按顺序执行 Vertx Future
How to execute Vertx Future in sequential order
在我的示例项目中,我尝试在应用程序启动时进行一些初始化工作。
- Java 16
- 顶点 4.1.0
log.info("Data initialization is starting...");
var deleteComments = this.comments.deleteAll().onSuccess(event -> log.info("deleted comments: {}", event));
var deletePosts = this.posts.deleteAll().onSuccess(event -> log.info("deleted posts: {}", event));
var deleteUsers = this.authors.deleteAll().onSuccess(event -> log.info("deleted users: {}", event));
//log.info("deleted rows: authors: {}, comments: {}, posts: {}", authorsDel, commentsDel, postDel);
var insertData = this.authors.create("user", "user@example.com").onSuccess(
authorId -> {
IntStream.range(1, 5)
.forEach(
i -> {
this.posts.create("Dgs post #" + i, "test content of #" + i, PostStatus.DRAFT.name(), authorId).onSuccess(
postId -> {
IntStream.range(1, new Random().nextInt(5) + 1)
.forEach(c -> this.comments.create("comment #" + c, postId));
}
);
}
);
}
);
var printPosts = this.posts.findAll().onSuccess(p -> log.info("post: {}", p));
var printComments = this.comments.findAll().onSuccess(p -> log.info("comment: {}", p));
var printAuthors = this.authors.findAll().onSuccess(p -> log.info("author: {}", p));
deleteComments
.flatMap(integer -> deletePosts)
.flatMap(integer -> deleteUsers)
.flatMap(integer -> insertData)
.flatMap( uuid -> printPosts)
.flatMap(postEntities -> printComments)
.flatMap(commentEntities -> printAuthors)
.onSuccess(event -> log.info("done"));
log.info("done data initialization...");
但它没有按预期工作。
- 没有像 Reactor 这样的
then
方法。
- 而
Future.result()
会return异常而不是阻塞调用(如何以阻塞方式执行,我认为是阻塞调用)。
我找不到按顺序执行它们的有效方法。
更新:
我按照建议更改了代码。
this.comments.deleteAll().onSuccess(event -> log.info("deleted comments: {}", event))
.flatMap(r -> this.posts.deleteAll().onSuccess(event -> log.info("deleted posts: {}", event)))
.flatMap(r -> this.authors.deleteAll().onSuccess(event -> log.info("deleted users: {}", event)))
.flatMap(r -> this.authors.create("user", "user@example.com")
.onSuccess(
authorId -> {
log.info("inserted user: {}", authorId);
IntStream.range(1, 5)
.forEach(
i -> {
this.posts.create("Dgs post #" + i, "test content of #" + i, PostStatus.DRAFT.name(), authorId).onSuccess(
postId -> {
log.info("inserted post: {}", postId);
IntStream.range(1, new Random().nextInt(5) + 1)
.forEach(c -> this.comments.create("comment #" + c, postId)
.onSuccess(id -> log.info("inserted comment: {}", id))
);
}
);
}
);
}
)
)
.flatMap(r -> this.posts.findAll().onSuccess(p -> log.info("saved posts: {}", p)))
.flatMap(r -> this.comments.findAll().onSuccess(p -> log.info("saved comments: {}", p)))
.flatMap(r -> this.authors.findAll().onSuccess(p -> log.info("saved authors: {}", p)))
.onSuccess(event -> log.info("done data initialization..."));
并在控制台得到如下日志。
10:20:46.699 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - Data initialization is starting...
10:20:47.768 [vert.x-eventloop-thread-1] INFO com.example.demo.MainVerticle - HTTP server started on port 8080
10:20:47.768 [vert.x-eventloop-thread-0] INFO i.v.c.i.l.c.VertxIsolatedDeployer - Succeeded in deploying verticle
10:20:47.918 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted comments: 10
10:20:47.942 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted posts: 4
10:20:47.960 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted users: 1
10:20:48.022 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted user: 260fee93-cf60-408d-a3e9-f7b08ed7545a
10:20:48.047 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved posts: []
10:20:48.052 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 57a936e2-9611-43b5-94e2-1b01069cd327
10:20:48.056 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved comments: []
10:20:48.067 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved authors: [AuthorEntity[id=260fee93-cf60-408d-a3e9-f7b08ed7545a, name=user, email=user@example.co
m, createdAt=null]]
10:20:48.092 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - done data initialization...
10:20:48.112 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 534b99ae-4847-4cea-84c1-88cea87f20b7
10:20:48.117 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: f7dca2eb-0954-4368-b9b6-68a00f6748f2
10:20:48.120 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 02e8f84f-25dd-4d69-b7f1-8c125ce35bc1
10:20:48.131 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: b9bf618a-f579-48f5-96cc-51f962ca041c
10:20:48.134 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: 052cfde8-627d-4cb3-8812-5543673a20ea
10:20:48.143 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: 69a5dc2b-30f8-4008-90a1-e8c724336dcd
10:20:48.149 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: a19c2626-1546-4ba0-a663-823df08d836f
如何确保 insert 块中的所有期货在输入 print 结果之前完成。
这很可能是因为您的 deleteAll
和 findAll
操作并不懒惰。正因为如此,您一给他们打电话,他们就会 运行ning。而不是做:
deleteComments
.flatMap(integer -> deletePosts)
...
您想这样做:
deleteComments
.flatMap(integer -> this.posts.deleteAll())
...
这将确保他们将 运行 按顺序进行。如果你想要更类似于 Reactor 的东西,你可以看看 RxJava3 extensions or mutiny bindings for Vert.x.
在我的示例项目中,我尝试在应用程序启动时进行一些初始化工作。
- Java 16
- 顶点 4.1.0
log.info("Data initialization is starting...");
var deleteComments = this.comments.deleteAll().onSuccess(event -> log.info("deleted comments: {}", event));
var deletePosts = this.posts.deleteAll().onSuccess(event -> log.info("deleted posts: {}", event));
var deleteUsers = this.authors.deleteAll().onSuccess(event -> log.info("deleted users: {}", event));
//log.info("deleted rows: authors: {}, comments: {}, posts: {}", authorsDel, commentsDel, postDel);
var insertData = this.authors.create("user", "user@example.com").onSuccess(
authorId -> {
IntStream.range(1, 5)
.forEach(
i -> {
this.posts.create("Dgs post #" + i, "test content of #" + i, PostStatus.DRAFT.name(), authorId).onSuccess(
postId -> {
IntStream.range(1, new Random().nextInt(5) + 1)
.forEach(c -> this.comments.create("comment #" + c, postId));
}
);
}
);
}
);
var printPosts = this.posts.findAll().onSuccess(p -> log.info("post: {}", p));
var printComments = this.comments.findAll().onSuccess(p -> log.info("comment: {}", p));
var printAuthors = this.authors.findAll().onSuccess(p -> log.info("author: {}", p));
deleteComments
.flatMap(integer -> deletePosts)
.flatMap(integer -> deleteUsers)
.flatMap(integer -> insertData)
.flatMap( uuid -> printPosts)
.flatMap(postEntities -> printComments)
.flatMap(commentEntities -> printAuthors)
.onSuccess(event -> log.info("done"));
log.info("done data initialization...");
但它没有按预期工作。
- 没有像 Reactor 这样的
then
方法。 - 而
Future.result()
会return异常而不是阻塞调用(如何以阻塞方式执行,我认为是阻塞调用)。
我找不到按顺序执行它们的有效方法。
更新:
我按照建议更改了代码。
this.comments.deleteAll().onSuccess(event -> log.info("deleted comments: {}", event))
.flatMap(r -> this.posts.deleteAll().onSuccess(event -> log.info("deleted posts: {}", event)))
.flatMap(r -> this.authors.deleteAll().onSuccess(event -> log.info("deleted users: {}", event)))
.flatMap(r -> this.authors.create("user", "user@example.com")
.onSuccess(
authorId -> {
log.info("inserted user: {}", authorId);
IntStream.range(1, 5)
.forEach(
i -> {
this.posts.create("Dgs post #" + i, "test content of #" + i, PostStatus.DRAFT.name(), authorId).onSuccess(
postId -> {
log.info("inserted post: {}", postId);
IntStream.range(1, new Random().nextInt(5) + 1)
.forEach(c -> this.comments.create("comment #" + c, postId)
.onSuccess(id -> log.info("inserted comment: {}", id))
);
}
);
}
);
}
)
)
.flatMap(r -> this.posts.findAll().onSuccess(p -> log.info("saved posts: {}", p)))
.flatMap(r -> this.comments.findAll().onSuccess(p -> log.info("saved comments: {}", p)))
.flatMap(r -> this.authors.findAll().onSuccess(p -> log.info("saved authors: {}", p)))
.onSuccess(event -> log.info("done data initialization..."));
并在控制台得到如下日志。
10:20:46.699 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - Data initialization is starting...
10:20:47.768 [vert.x-eventloop-thread-1] INFO com.example.demo.MainVerticle - HTTP server started on port 8080
10:20:47.768 [vert.x-eventloop-thread-0] INFO i.v.c.i.l.c.VertxIsolatedDeployer - Succeeded in deploying verticle
10:20:47.918 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted comments: 10
10:20:47.942 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted posts: 4
10:20:47.960 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - deleted users: 1
10:20:48.022 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted user: 260fee93-cf60-408d-a3e9-f7b08ed7545a
10:20:48.047 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved posts: []
10:20:48.052 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 57a936e2-9611-43b5-94e2-1b01069cd327
10:20:48.056 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved comments: []
10:20:48.067 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - saved authors: [AuthorEntity[id=260fee93-cf60-408d-a3e9-f7b08ed7545a, name=user, email=user@example.co
m, createdAt=null]]
10:20:48.092 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - done data initialization...
10:20:48.112 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 534b99ae-4847-4cea-84c1-88cea87f20b7
10:20:48.117 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: f7dca2eb-0954-4368-b9b6-68a00f6748f2
10:20:48.120 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted post: 02e8f84f-25dd-4d69-b7f1-8c125ce35bc1
10:20:48.131 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: b9bf618a-f579-48f5-96cc-51f962ca041c
10:20:48.134 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: 052cfde8-627d-4cb3-8812-5543673a20ea
10:20:48.143 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: 69a5dc2b-30f8-4008-90a1-e8c724336dcd
10:20:48.149 [vert.x-eventloop-thread-1] INFO com.example.demo.DataInitializer - inserted comment: a19c2626-1546-4ba0-a663-823df08d836f
如何确保 insert 块中的所有期货在输入 print 结果之前完成。
这很可能是因为您的 deleteAll
和 findAll
操作并不懒惰。正因为如此,您一给他们打电话,他们就会 运行ning。而不是做:
deleteComments
.flatMap(integer -> deletePosts)
...
您想这样做:
deleteComments
.flatMap(integer -> this.posts.deleteAll())
...
这将确保他们将 运行 按顺序进行。如果你想要更类似于 Reactor 的东西,你可以看看 RxJava3 extensions or mutiny bindings for Vert.x.