刚刚开始使用 Mutiny,完成指南 ( https://smallrye.io/smallrye-mutiny/guides )。据我在文档中读到,调用方法是异步的( https://smallrye.io/smallrye-mutiny/getting-started/observing-events )。
但是,通过一个小片段,可以发现 call 方法正在阻塞执行,因此根据我的理解,它不是异步的。这里的错误/误解在哪里?
Uni.createFrom().item("bla")
.onItem().invoke(i -> LOG.info("before call"))
.onItem().call(i -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Uni.createFrom().voidItem();
}
)
.subscribe().with(i -> LOG.info("after call process. result=" + i));
日志输出
11:40:11.026 INFO [main] ....mutiny.vertx.HelloUni - before call
11:40:16.032 INFO [main] ....mutiny.vertx.HelloUni - after call process. result=bla
最佳答案
每个订阅者(这里我们有 1 个来自主线程的订阅者)将尝试(单独)解析 Uni.当它到达 call
lambda 时,它只是在链中创建新 Uni 之前阻塞在 Thread.sleep
调用中。
传递给 .call
或 .transformToUni
的函数不应阻塞内部 I/O(sleep
正在这样做),而是发起 I/O 请求并立即返回 Uni。
顺便说一句,如果我们想发出延迟(非阻塞),我们可以这样做:
Uni<String> uni1 = Uni.createFrom().item("bla")
.onItem().invoke(s -> logger.info("before call"))
.onItem().delayIt().by(Duration.ofSeconds(3));
uni1.subscribe().with(s -> logger.info("after: result=" + s));
logger.info("main continues its work ...");
...
关于java - 为什么 Mutiny 调用方法会阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71882523/