Scala未来阻碍了转换



我有以下测试代码段:

import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
import scala.util.Success
import scala.concurrent.ExecutionContext.Implicits.global
object FutureAndThen extends App {
  val future = Future {
    println("Started initial Future")
    10
  } andThen { case Success(value) =>
    println("Started callback")
    Thread.sleep(5000)
    println(s"Finished callback: value = $value")
  } map { x =>
    println("Chained transformation")
    x * 2
  }
  println(Await.result(future, Duration.Inf))
}

它产生以下输出:

Started initial Future
Started callback
Finished callback: value = 10
Chained transformation
20

我希望andThen回调能够异步执行。但是实际执行是下一个:

  1. 执行原始未来
  2. 执行 asynchronous 呼叫
  3. 运行转换(map

首先,我认为问题是在ExecutionContext中,该问题决定以单线线程运行所有这些操作。我将其更改为使用自定义ExecutionContext

implicit val ctx = ExecutionContext.fromExecutor(
  (command: Runnable) => new Thread(command).start()
)

结果是相同的。你能建议我我缺少什么吗?

实际上记录了Future.andThen的行为:

将副作用函数应用于未来的结果,并返回 A 新的未来与这一未来有关。

此方法允许一种允许 emforce ,即在指定订单中执行回调。

这意味着在andThen内部的计算完成之前,map不会启动其作业。如果这不是您想要的,则必须在原始Future上调用map。然后,您可以使用onComplete而不是andThen,因此代码将成为这样的东西:

  val future = Future {
    println("Started initial Future")
    10
  }
  future onComplete { case Success(value) =>
    println("Started callback")
    Thread.sleep(2000)
    println(s"Finished callback: value = $value")
  }
  val f2 = future map { x =>
    println("Chained transformation")
    x * 2
  }
  println(Await.result(f2, Duration.Inf))

P.S。AFAIK没有标准的onComplete等效物可以与方法链式一起使用,我认为这是通过设计来使通过阅读代码更容易预测行为的方法。当前,您可以使用一个简单的规则:如果将其链接 - 稍后执行。

最新更新