这是计算经过时间的另一种方法,可能需要更多的定制(比如故障处理,NonFatal
很可能),但我认为这更习惯用语。它只适用于Future
s。
首先为带有时间的结果创建一个类(也可以用一个元组替换),并为带有时间的失败创建一个类。
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
case class ResultWithTime[ResultType](val result: ResultType, val time: Long)
class FailureWithTime(failure: Throwable, val time: Long) extends Throwable(failure)
然后创建一个包装未来执行的方法,并在它失败时处理这种情况(Promise
如果您不喜欢Future
'smap
和recoverWith
方法(因为它们需要隐式ExecutionContext
),可能会使用)。
object TimerFuture {
def apply[ResultType](fut: =>Future[ResultType]): Future[ResultWithTime[ResultType]] = {
val startTime = System.currentTimeMillis
fut.map(r => ResultWithTime(r, System.currentTimeMillis - startTime))
.recoverWith{case t:Throwable =>
Future.failed(new FailureWithTime(t, System.currentTimeMillis - startTime))
}
}
}
这是一个如何使用它的示例:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.io.StdIn
object Y extends App {
TimerFuture(Future{Thread.sleep(200); "Hello"})
.onSuccess({case ResultWithTime(r, t) => println(s"Took $t ms to get: $r")})
TimerFuture(Future{Thread.sleep(100); throw new NullPointerException()})
.onFailure({case f: FailureWithTime => println(s"Took ${f.time} ms to get: ${f.getCause}")})
StdIn.readLine()
}