scalaz.concurrent.Task repeatEval 只计算 Task.now 和 Task.async 一次
scalaz.concurrent.Task repeatEval only evaluate Task.now and Task.async once
我目前正在学习 scalaz 流,我很困惑为什么 repeatEval 只计算 Task.async 一次。
val result = Process
.repeatEval(Task.async[Unit](t => {
val result = scala.io.Source.fromURL("http://someUrl").mkString
println(".......")
println(result)
}))
result.runLog.run //only print once
但是,如果我将 Task.async 更改为 Task.delay。它无限地评估函数。我不知道为什么
val result = Process
.repeatEval(Task.delay({
val result = scala.io.Source.fromURL("http://someUrl").mkString
println(".......")
println(result)
}))
result.runLog.run //print infinitely
非常感谢
正如我在 中针对您最近关于 Task
的问题所提到的,Task.async
采用了一个注册回调的函数,而不是一些应该异步执行的代码。对于另一个问题,您实际上想要 Task.async
,因为您正在与基于回调的 API.
进行互操作
这里看起来你可能想要 Task.apply
,而不是 Task.delay
。两者看起来很相似,但 delay
只是暂停计算——它不在单独的线程中使用 ExecutorService
到 运行。您可以在以下示例中看到这一点:
import scalaz._, Scalaz._, concurrent._
val delayTask = Task.delay(Thread.sleep(5000))
val applyTask = Task(Thread.sleep(5000))
Nondeterminism[Task].both(delayTask, delayTask).run
Nondeterminism[Task].both(applyTask, applyTask).run
delayTask
版本需要更长的时间。
我目前正在学习 scalaz 流,我很困惑为什么 repeatEval 只计算 Task.async 一次。
val result = Process
.repeatEval(Task.async[Unit](t => {
val result = scala.io.Source.fromURL("http://someUrl").mkString
println(".......")
println(result)
}))
result.runLog.run //only print once
但是,如果我将 Task.async 更改为 Task.delay。它无限地评估函数。我不知道为什么
val result = Process
.repeatEval(Task.delay({
val result = scala.io.Source.fromURL("http://someUrl").mkString
println(".......")
println(result)
}))
result.runLog.run //print infinitely
非常感谢
正如我在 Task
的问题所提到的,Task.async
采用了一个注册回调的函数,而不是一些应该异步执行的代码。对于另一个问题,您实际上想要 Task.async
,因为您正在与基于回调的 API.
这里看起来你可能想要 Task.apply
,而不是 Task.delay
。两者看起来很相似,但 delay
只是暂停计算——它不在单独的线程中使用 ExecutorService
到 运行。您可以在以下示例中看到这一点:
import scalaz._, Scalaz._, concurrent._
val delayTask = Task.delay(Thread.sleep(5000))
val applyTask = Task(Thread.sleep(5000))
Nondeterminism[Task].both(delayTask, delayTask).run
Nondeterminism[Task].both(applyTask, applyTask).run
delayTask
版本需要更长的时间。