我不是 scalaz 专家,但我会尽力帮助您。让我试着一一回答你的问题:
1) 谁能分享一下他用scalaz编写并发/异步应用程序的经验,基本上如何正确使用它的异步方法?
我们先来看看async签名:
def async[A](listen: (A => Unit) => Unit): Future[A]
起初这可能有点神秘,因此最好查看测试以了解可能的用例。在https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/concurrent/FutureTest.scala
你可以找到以下代码:
"when constructed from Future.async" ! prop{(n: Int) =>
def callback(call: Int => Unit): Unit = call(n)
Future.async(callback).run must_==
}
正如我们从签名Future.async 知道的那样,只需使用签名(A => Unit) => Unit 的函数构造新的Future。这真正意味着 Future.async 将作为参数函数,对于给定的回调进行所有必需的计算并将结果传递给该回调。
需要注意的是,Future.async 本身不会运行任何计算,它只是准备结构以便稍后运行它们。
2) 据我了解,异步不使用单独的线程,例如调用标准未来,或者来自 scalaz 的 fork/apply 方法,那么为什么它被称为异步呢?
你是对的。只有fork 和apply 似乎在使用线程运行任何东西,这很容易注意到查看包含implicit pool: ExecutorService 的签名。我不能在这里代表作者发言,但我猜异步与回调有关。这意味着您将使用异步回调,而不是阻塞 Future 以获得最终结果。
3) 这是否意味着为了与 scalaz 获得真正的并发性,我总是必须调用 fork(now(...)) 或 apply?
据我所知,是的。请注意,当您使用语法 Future(x) 创建 Future 时,您在这里使用的是 apply 方法,所以这是一种默认行为(这很好)。
如果您想更好地了解 Scalaz Futures 的设计,我可以推荐您阅读 "Functional Programming in Scala"。我相信这本书是由主要的 Scalaz 贡献者编写的,第 7 章讨论了为纯函数并行库设计 API。它与 Scalaz Future 并不完全相同,但您可以看到许多相似之处。