java – 直接从CompletableFuture.thenAccept返回值
我试图从CompletableFuture返回一个列表,如下所示:
public List<Provider> get() { CompletableFuture<List<Provider>> providersResponse = getSomeData(); return providersResponse.thenAccept((List<Provider> providers) -> { return providers; }); } 它失败了“意外的返回类型.但是如何以异步方式返回结果? 解决方法
你的目标存在根本矛盾.您只能使用get()返回完整的,可直接使用的列表或“以异步方式返回结果”.
如果方法List< Provider> get()应该返回一个List,它可以被调用者无限制地使用,它不能保持异步操作,因为当get()返回时操作必须已经完成.这可以像调用join()一样简单,等待完成并获得结果: public List<Provider> get() { CompletableFuture<List<Provider>> providersResponse = getSomeData(); return providersResponse.join(); } 要不就 public List<Provider> get() { return getSomeData().join(); } 这有效地将getSomeData()的潜在异步操作转换为同步操作. This answer,使用 public List<Provider> get() { List<Provider> providers = new ArrayList<>(); CompletableFuture<List<Provider>> providersResponse = getSomeData(); providersResponse.thenAccept(providers::addAll); return providers; } 不等待操作完成,但在调度addAll操作后返回一个新的ArrayList,该操作的执行完全不受此方法的控制. 这是一个异步操作,因此当get()返回时,List可能仍然是空的,但稍后会被任意线程更新.由于ArrayList不是线程安全的,因此感知状态不必是,空的或完成的,它可以是任意的中间状态,甚至不需要是一致的.在使用该代码时,要为奇怪的异常,看起来不可能的情况或其他惊喜做好准备. 当您通过使用线程安全List实现来修复该代码时,仍然会遇到以下问题:返回的List在查询时可能为空,并在调用者控件之外的任意时间点填充.这是不可修复的,如开头所说,这是想要异步操作但返回List的基本问题. CompletableFuture已经是潜在异步操作的封装,因此如果您希望操作保持异步,只需返回CompletableFuture< List< Provider>>给来电者,以便获得控制权.否则,如果您希望调用者接收可以无限制使用的List,请在返回结果之前等待完成,例如通过join(). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |