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 版本需要更长的时间。