我有兩種方法,我們稱它們爲load()
和init()
。每個人都在自己的線程中啓動一個計算,並在其自己的執行上下文中返回Future
。這兩個計算是獨立的。用回調編寫兩個Scala未來,沒有第三個ExecutionContext
val loadContext = ExecutionContext.fromExecutor(...)
def load(): Future[Unit] = {
Future
}
val initContext = ExecutionContext.fromExecutor(...)
def init(): Future[Unit] = {
Future { ... }(initContext)
}
我想這兩個來自一些三線程中調用 - 說這是從main()
- 並且都完成後執行一些其他的計算。
def onBothComplete(): Unit = ...
現在:
- 我不在乎它完成第一
- 我不在乎什麼的線程上執行其它計算,除了:
- 我不想阻止兩個線程等待另一個線程;
- 我不想阻塞第三個(調用)線程;和
- 我不想爲了設置標誌而開始第四個線程。
如果我用-內涵,我得到的是這樣的:
val loading = load()
val initialization = initialize()
for {
loaded <- loading
initialized <- initialization
} yield { onBothComplete() }
,我得到無法找到一個隱含的ExecutionContext。
我認爲這意味着斯卡拉希望第四個線程等待兩個期貨的完成並設置標誌,無論是明確的新的ExecutionContext
還是ExecutionContext.Implicits.global
。所以看起來理解力已經不存在了。
我想我也許可以嵌套回調:
initialization.onComplete {
case Success(_) =>
loading.onComplete {
case Success(_) => onBothComplete()
case Failure(t) => log.error("Unable to load", t)
}
case Failure(t) => log.error("Unable to initialize", t)
}
不幸的是onComplete
也需要一個隱含的ExecutionContext
,我也得到了同樣的錯誤。 (另外,這是難看的,並且從loading
失去錯誤消息,如果initialization
失敗。)
是否有任何方式來組成的Scala期貨而不阻塞和不引入另一個ExecutionContext
?如果沒有,我可能不得不把它們扔給Java 8 CompletableFutures或
Javaslang
Vavr Futures,它們都能夠在執行原始工作的線程上運行回調。
更新澄清阻塞兩個等待另一個的線程也是不可接受的。
再次更新對於完成後計算沒有那麼具體。
你應該做'Future.firstCompletedOf(名單(初始化,加載))'如果你想抓住未來的結果首先完成。爲了列表理解將等待兩個期貨在完成收益之前完成。 – pcting
@pcting在執行其他計算之前,我確實希望等待兩個期貨的完成。我不想阻止當前的線程來做到這一點。 –
如果這是爲了將AtomicBoolean設置爲true的確切目的,那麼可以改爲在完成時指示完成。 'promise.completeWith(初始化zip加載)' –