在Scala中返回之前记录未来的值

时间:2016-02-25 02:59:00

标签: scala

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
    }

2 个答案:

答案 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操作。