26

我刚刚开始学习 Play 2.0 框架。我无法理解的一件事是play tutorial中描述的 Iteratee、Enumerator 和 Enumeratee 模式。我在函数式语言方面的经验很少。

这个模式有什么作用?

它如何帮助我编写非阻塞/反应式代码?

一些简单的例子会有所帮助。

4

1 回答 1

19

playframework 2.0 下载附带一些示例。其中两个有 Iteratee/Comet 示例。例如,comet-clock示例应用程序显示:

lazy val clock = Enumerator.fromCallback { () =>
  Promise.timeout(Some(dateFormat.format(new Date)), 100 milliseconds)
}

然后它是这样使用的:

Ok.stream(clock &> Comet(callback = "parent.clockChanged"))

这会将结果以块的形式提供给客户端。该Enumerator对象还具有fromFile, fromStream(如java.io.InputStream)实用枚举器函数。

我不确定这是在哪里完成的,但假设这个分块处理没有占用线程。看到一些基准测试会非常有趣,因为迭代器的实现肯定存在开销,因为要处理的数据以及计算被包装在各种对象中。

从枚举器提供的数据被包装,以便它可以指示有更多数据要处理或数据已到达末尾 (EOF)。迭代器的处理结果也被包装,以便它可以指示是否已经在某些输入上计算了结果,或者需要更多输入来计算结果。我推荐 John De Goes 的nescala 演示文稿,它展示了从 fold 到 Iteratees 的演变。编辑:Brendan McAdams 有一个关于异步和非阻塞的 Scala Days 2012演示文稿- 在演示文稿结束时(约 26 分钟),它涉及迭代器以及它如何帮助以异步样式处理数据库游标样式 IO。

一个被吹捧的好处Iteratees是他们组成。以下是它们的几种组合方式:

  • 你可以喂一个枚举器然后另一个
  • 您可以将类型函数映射(T) => U到枚举器上T以获取枚举器U
  • 你可以交错两个枚举器
  • 一个 iteratee 可以留下一些输入供另一个 iteratee 使用
于 2012-04-17T01:44:45.070 回答