Scala Future 会阻止转换吗?
Scala Future blocks transformations?
我有以下测试代码片段:
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
回调异步执行。但真正执行的是下一个:
- 执行原始未来
- 执行异步回调
- 运行 变换 (
map
)
起初我认为问题出在 ExecutionContext
中,它决定 运行 在单线程中进行所有这些操作。我将其更改为使用自定义 ExecutionContext
:
implicit val ctx = ExecutionContext.fromExecutor(
(command: Runnable) => new Thread(command).start()
)
结果是一样的。你能告诉我我缺少什么吗?
此行为实际上记录在 Future.andThen
:
Applies the side-effecting function to the result of this future, and returns
a new future with the result of this future.
This method allows one to enforce that the callbacks are executed in a specified order.
意思是map
在andThen
里面的计算完成之前不会开始它的工作。如果这不是你想要的,你必须在原来的 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。据我所知,没有可与方法链接一起使用的标准 onComplete
等价物,我认为这是设计使然,通过阅读代码更容易预测行为。目前你可以使用一个简单的规则:如果它被链接 - 它稍后执行。
我有以下测试代码片段:
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
回调异步执行。但真正执行的是下一个:
- 执行原始未来
- 执行异步回调
- 运行 变换 (
map
)
起初我认为问题出在 ExecutionContext
中,它决定 运行 在单线程中进行所有这些操作。我将其更改为使用自定义 ExecutionContext
:
implicit val ctx = ExecutionContext.fromExecutor(
(command: Runnable) => new Thread(command).start()
)
结果是一样的。你能告诉我我缺少什么吗?
此行为实际上记录在 Future.andThen
:
Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.
This method allows one to enforce that the callbacks are executed in a specified order.
意思是map
在andThen
里面的计算完成之前不会开始它的工作。如果这不是你想要的,你必须在原来的 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。据我所知,没有可与方法链接一起使用的标准 onComplete
等价物,我认为这是设计使然,通过阅读代码更容易预测行为。目前你可以使用一个简单的规则:如果它被链接 - 它稍后执行。