java - 调用使用 CompletableFuture 的 thenAccept() 的方法
问题描述
我有一个返回 DeferredResult 类型的对象的 rest API 函数。
import org.springframework.web.context.request.async.DeferredResult;
public DeferredResult<Object> apiMethod{
CompletableFuture<Object> future = someMethod();
final DeferredResult<Object> response = new DeferredResult<>();
future.thenAccept(){
//logic to populate response
}
return response;
}
我正在编写一个函数,它将调用 apiMethod() 并使用它的响应。我总是最终得到一个空响应,因为在 future.thenAccept () 中填充了响应。有没有办法处理这个?
解决方案
问题是该方法在thenAccept
异步运行时继续执行。在您调用 之后thenAccept
,该方法只会在response
之后返回,与它是否已经填充无关。
想象一下下面的简单代码:
public static void main(String[] args) {
AtomicReference<String> result = new AtomicReference<>(null);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
for (int i = 0; i < 100_000_000; i++) {}
return "Hello World!";
});
future.thenAccept(s -> {
result.compareAndSet(null, s);
});
System.out.println(result.get());
}
您可能希望"Hello World!"
打印出来,但事实并非如此;它打印出来null
。这是同样的问题:主线程打印该值,该值将在某个时候异步更新。您可以通过加入未来来解决此问题:
public static void main(String[] args) {
AtomicReference<String> result = new AtomicReference<>(null);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
for (int i = 0; i < 100_000_000; i++) {}
return "Hello World!";
});
CompletableFuture<Void> end = future.thenAccept(s -> {
result.compareAndSet(null, s);
});
end.join();
System.out.println(result.get());
}
现在,当我们加入异步未来链,或者更确切地说是设置值的一个未来时,我们将看到主线程打印出来,"Hello World!"
因为它会等待未来完成。
现在你只需要在你的代码中应用这个修复。
推荐阅读
- javascript - Phaser 3如何全屏显示
- python - 查找所有*不*匹配正则表达式的单词/子字符串?
- python - 动态生成器解包
- highcharts - 有没有办法只在 exporting.csv 中显示 PNG 选项?
- amazon-web-services - 如何从 Lambda 调用 API
- javascript - 解决函数中的承诺
- user-interface - 在列中居中小部件
- desire2learn - 如何使用 D2L REST API 设置截止日期?
- php - 每个 PHP 错误都会导致 nginx 500 错误,而不是显示 PHP 错误数据
- asp.net-core - .NET Core - 带有 Web 服务的本地应用程序