假设我有几个函数返回Future
:
def fab(a: A, timeOutMillis: Long): Future[B] = ???
def fbc(b: B, timeOutMillis: Long): Future[C] = ???
def fcd(c: C, timeOutMillis: Long): Future[D] = ???
如果timeOutMillis > 0
,则函数返回在timeOutMillis
时间段内完成的期货。否则,它们返回一个失败的Future
。
现在我想编写这些函数来编写fac
和fad
:
def fac(a: A, timeOutMillis: Long): Future[C] = ???
def fad(a: A, timeOutMillis: Long): Future[D] = ???
所以我可以这样实现fac
:
def fac(a: A, timeOutMillis: Long): Future[C] = {
val startTime = System.currentTimeMillis()
for {
b <- fab(a, timeOutMillis)
timeAB = System.currentTimeMillis() - startTime
c <- fbc(b, timeOutMillis - timeAB)
} yield c
}
注意,我不想等待完成期货,因此我不使用Await
。
这个fac
实现可能会工作,但它看起来很笨拙,并且包含样板代码
您如何建议链Futures
超时?
附言:我正在考虑覆盖Future
的flatMap
来计算下一个超时。你觉得怎么样?
我想,您正在寻找scala.duration.Deadline
。
d = timeoutMillis.millis.fromNow
fab(a, d.timeLeft.toMillis)
.flatMap(fbc(_, d.timeLeft.toMillis))
.flatMap(fcd(_, d.timeLeft.toMillis))
如果你不喜欢重复d.timeTimeLeft.toMillis
咒语,你可以把它折叠起来,也可以把它推广到任何数字连锁呼叫数:
Seq(fab _, fbc _, fcd _)
.foldLeft(Future(a)) { case (last, next) =>
last.flatMap(next(_, d.timeLeft.toMillis))
}
为什么不:
import scala.concurrent.{Await,Future}
Await.ready(fut1, 5.seconds).flatMap { sucInTime =>
fut2
}