Thay vào đó, bạn có thể sử dụng cách hiểu như sau:
val fut1 = Future{...}
val fut2 = Future{...}
val fut3 = Future{...}
val aggFut = for{
f1Result <- fut1
f2Result <- fut2
f3Result <- fut3
} yield (f1Result, f2Result, f3Result)
Trong ví dụ này, hợp đồng tương lai 1, 2 và 3 được bắt đầu song song. Sau đó, trong phần đọc hiểu, chúng ta đợi cho đến khi có kết quả 1 rồi đến 2 và 3. Nếu 1 hoặc 2 không thành công, chúng tôi sẽ không đợi 3 nữa. Nếu cả 3 đều thành công, thì aggFut
val sẽ giữ một bộ giá có 3 chỗ trống, tương ứng với kết quả của 3 tương lai.
Bây giờ, nếu bạn cần hành vi mà bạn muốn dừng chờ đợi nếu trước tiên nói rằng fut2 không thành công, mọi thứ sẽ phức tạp hơn một chút. Trong ví dụ trên, bạn sẽ phải đợi fut1 hoàn thành trước khi nhận ra rằng fut2 không thành công. Để giải quyết điều đó, bạn có thể thử một cái gì đó như sau:
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)
}
Bây giờ điều này hoạt động chính xác, nhưng vấn đề đến từ việc biết cái nào Future
để loại bỏ Map
khi một cái đã được hoàn thành thành công. Miễn là bạn có một số cách để tương quan đúng một kết quả với Tương lai đã tạo ra kết quả đó, thì điều gì đó tương tự sẽ hoạt động. Nó chỉ đệ quy tiếp tục xóa các Hợp đồng tương lai đã hoàn thành khỏi Bản đồ và sau đó gọi Future.firstCompletedOf
phần còn lại Futures
cho đến khi không còn lại, thu thập kết quả trên đường đi. Nó không đẹp, nhưng nếu bạn thực sự cần hành vi mà bạn đang nói, thì điều này hoặc thứ gì đó tương tự có thể hoạt động.