Anda bisa menggunakan pemahaman-untuk sebagai berikut:
val fut1 = Future{...}
val fut2 = Future{...}
val fut3 = Future{...}
val aggFut = for{
f1Result <- fut1
f2Result <- fut2
f3Result <- fut3
} yield (f1Result, f2Result, f3Result)
Dalam contoh ini, kontrak berjangka 1, 2, dan 3 dimulai secara paralel. Kemudian, dalam pemahaman kita menunggu sampai hasil 1 dan kemudian 2 dan kemudian 3 tersedia. Jika 1 atau 2 gagal, kami tidak akan menunggu 3 lagi. Jika ketiganya berhasil, maka aggFut
val akan menahan tupel dengan 3 slot, sesuai dengan hasil dari 3 futures.
Sekarang jika Anda membutuhkan perilaku di mana Anda ingin berhenti menunggu jika mengatakan fut2 gagal terlebih dahulu, semuanya menjadi sedikit lebih rumit. Dalam contoh di atas, Anda harus menunggu fut1 selesai sebelum menyadari fut2 gagal. Untuk mengatasinya, Anda bisa mencoba sesuatu seperti ini:
val fut1 = Future{Thread.sleep(3000);1}
val fut2 = Promise.failed(new RuntimeException("boo")).future
val fut3 = Future{Thread.sleep(1000);3}
def processFutures(futures:Map[Int,Future[Int]], values:List[Any], prom:Promise[List[Any]]):Future[List[Any]] = {
val fut = if (futures.size == 1) futures.head._2
else Future.firstCompletedOf(futures.values)
fut onComplete{
case Success(value) if (futures.size == 1)=>
prom.success(value :: values)
case Success(value) =>
processFutures(futures - value, value :: values, prom)
case Failure(ex) => prom.failure(ex)
}
prom.future
}
val aggFut = processFutures(Map(1 -> fut1, 2 -> fut2, 3 -> fut3), List(), Promise[List[Any]]())
aggFut onComplete{
case value => println(value)
}
Sekarang ini berfungsi dengan benar, tetapi masalahnya berasal dari mengetahui mana yang Future
harus dihapus dari Map
ketika seseorang telah berhasil diselesaikan. Selama Anda memiliki cara untuk mengkorelasikan hasil dengan Masa Depan yang melahirkan hasil tersebut, maka sesuatu seperti ini berhasil. Itu hanya secara rekursif terus menghapus Futures yang sudah selesai dari Peta dan kemudian memanggil Future.firstCompletedOf
yang tersisa Futures
sampai tidak ada yang tersisa, mengumpulkan hasil di sepanjang jalan. Ini tidak bagus, tetapi jika Anda benar-benar membutuhkan perilaku yang Anda bicarakan, maka ini, atau sesuatu yang serupa bisa berhasil.