将未来[T]转变为未来[试试[T]]

时间:2016-03-07 20:00:10

标签: scala future

我想了解以下答案How to carry on executing Future sequence despite failure?。 (希望这不值得投票,因为我试图理解这里的代码。)

我不明白mapValue如何将Future [T]转换为Future [Try [T]]

def mapValue[T]( f: Future[T] ): Future[Try[T]] = {
  val prom = Promise[Try[T]]()
  f onComplete prom.success
  prom.future
}

第f条onComplete prom.success,它在做什么。我的理解是prom.success必须采用Try [T]类型的对象,但在这里它不会这样做。此外,没有赋值给f将Future [T]转换为Future [Try [T]]。 此外,对未来的反应应该是副作用,并且应该返回相同的未来价值,因此不确定转换是如何发生的。

2 个答案:

答案 0 :(得分:2)

Scala编译器将f onComplete prom.success行解析如下:

  1. 在某些情况下可以省略点和圆括号,因此f onComplete x是一种写f.onComplete(x)的方式。
  2. 编译器看到onComplete方法作为参数函数f: Try[T] => U。您还传递了一个函数作为参数Promise#success,它具有兼容的签名。
  3. 所以该方法正在做的是创建类型为Promise的新Try[T](可写的未来),并在原始未来完成时用已包装的Try[T]完成该承诺。然后它返回从promise获得的新Future[Try[T]]

答案 1 :(得分:1)

为了扩展Maxim的答案,f onComplete prom.success可以重写为:

f.onComplete(prom.success)

f.onComplete(prom.success(_))

f.onComplete { resultOfFutureAsTry =>
  prom.success(resultOfFutureAsTry)
}

prom.success设置承诺的成功值。因此,无论原始未来f内发生了什么,(抛出异常,或未来成功完成),新的未来(由prom.future返回,并在原始未来完成后创建)永远是一个成功的未来。有时,成功的未来包含Failure[T],有时还包含Success[T]

旁注:通常,f.onComplete更像是这样使用:

f.onComplete {
  case Success(x) => println(s"Yay, $x worked!")
  case Failure(ex) => println(s"Darn, it failed: $ex")
}

但这只是编写函数f: Try[T] => U的一种方便方法。