在这个版本中它毫无意义,因为CompletableFuture.completedFuture()
立即创建完成的Future。
但是,在一段更复杂的代码中,您可能会返回尚未完成的Future
。除非其他线程在此Future
上调用complete()
,Spring将不会发送响应主体。
为什么不只是使用一个新的线程?那么,你可以 - 但在某些情况下,它可能不会更有效。例如,您可以将一个任务放入一个Executor
以由一小群线程处理。
或者您可能会触发一个JMS消息,要求完全单独的机器处理该请求。程序的另一部分将响应传入的JMS消息,找到相应的Future
并完成它。在另一个系统上完成工作时,不需要专用于此HTTP请求的线程处于活动状态。
很简单的例子:
@RequestMapping("/employeenames/{id}")
public CompletableFuture<String> getName(@PathVariable String id){
CompletableFuture<String> future = new CompletableFuture<>();
database.asyncSelect(
name -> future.complete(name),
"select name from employees where id = ?",
id
);
return future;
}
我已经发明了一种似是而非的十岁上下的API在这里异步数据库客户端:asyncSelect(Consumer<String> callback, String preparedstatement, String... parameters)
。重点在于它会触发查询,然后不会阻止等待数据库响应。相反,它会为数据库客户端在可能时调用回调(name -> future.complete(name)
)。
这不是关于改进API响应时间 - 我们不会发送HTTP响应,直到我们有有效负载提供。这是关于如何更有效地使用服务器上的资源,以便在我们等待数据库响应时它可以做其他事情。
有一个相关的,但不同的概念非同步REST,其中服务器202 Accepted
和像Location: /queue/12345
头响应,允许客户端轮询结果。但这不是你询问的代码的作用。
那么使用CompleteableFuture有什么意义,为什么不使用一个新的线程呢?那么这样就完全不会改善API响应时间? – Bana
那么你会使用另一个线程。这是完成'CompletableFuture'并使结果被发送的那个。 – Kayaman
那么当人们说Async改善API响应时间时,这意味着什么。到底如何? – Bana