scalaz.concurrent.Task repeatEval只评估Task.now和Task.async一次

时间:2016-02-24 02:35:50

标签: scala scalaz

我正在学习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

非常感谢提前

1 个答案:

答案 0 :(得分:2)

正如我在my answer中提到的关于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版本需要更长时间。