在這個版本中它毫無意義,因爲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