def returnFuture[A](x: A): Future[A] = {
val xFuture = Future { x } // suppose an API call that returns a future
xFuture.flatMap(x => {
println(x) // logging the value of x
xFuture
})
}
这就是我目前的做法。提供更多背景信息:
当发出请求时,在API内部调用此函数,并且我希望在返回请求中计算的值之前打印日志消息。这就是为什么,以下对我来说不是一个好的解决方案:
def returnFuture[A](x: A): Future[A] = {
val xFuture = Future { x } // suppose an API call that returns a future
xFuture.map(x => {
println(x) // logging the value of x
})
xFuture
}
答案 0 :(得分:3)
日志记录是一种副作用,这意味着如果由于任何原因(例如调用toString
投掷NPE)失败,您不希望操作失败。
Future#andThen
非常适合此用例。来自文档:
将副作用函数应用于此未来的结果,并返回具有此未来结果的新未来。
此方法允许强制执行回调以指定顺序执行。
请注意,如果其中一个链式
andThen
回调引发异常,则该异常不会传播到后续andThen
回调。相反,随后的andThen
回调将被赋予此未来的原始值。
你的例子变成了:
def returnFuture[A](x: A): Future[A] = {
Future { x } // suppose an API call that returns a future
.andThen { case Success(v) => println(v) }
}
答案 1 :(得分:0)
您可以使用onComplete
回调:
def returnFuture[A](x: A): Future[A] = {
val f = Future { x }
f.onComplete(println)
f
}
地图也可以使用:
def returnFuture[A](x: A): Future[A] = {
Future { x }.map { v =>
println(v)
v
}
}
请注意,使用Futures
的重点在于您试图避免阻止,并且您无法准确控制何时执行Future
。因此,如果您想要更详细的日志,同时保持Future
的异步性质,请执行以下操作:
def doSomething(param: String): String = {
// log something here
val result = param.toUpperCase
// log something else here
result
}
def asFuture(param: String) = Future {
doSomething(param)
}
换句话说,如果这是一个选项,请改为将日志添加到x
操作。