在Play 2.0中无法理解Iteratee,Enumerator,Enumeratee

时间:2012-04-16 16:04:52

标签: scala playframework playframework-2.0 iterate

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

这种模式有什么作用?

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

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

1 个答案:

答案 0 :(得分:19)

playframework 2.0下载附带一些示例。其中两个有Iteratee / Comet示例。例如,彗星时钟sample app显示:

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

然后就像这样使用:

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

将以块的形式将结果提供给客户端。 Enumerator对象还有一个fromFilefromStream(如java.io.InputStream)实用程序枚举函数。

我不确定这是做什么的,但假设这个分块处理不会占用线程。看到一些基准测试会非常有趣,因为迭代器的实现肯定会产生开销,因为要处理的数据以及计算都包含在各种对象中。

从枚举器馈送的数据被包装,以便它可以指示有更多数据要处理或数据已到达终点(EOF)。迭代的处理结果也被包装,以便它可以指示是否已经在某个输入上计算了结果,或者需要更多输入来计算结果。我推荐John De Goes'nescala presentation,它展示了从折叠到Iteratees的演变。编辑:Brendan McAdams在异步和非阻塞方面有一个很好的Scala Days 2012 presentation - 在演示结束时(~26分钟)它触及迭代,以及它如何帮助处理异步风格的数据库光标样式IO。

Iteratees的一个被吹捧的好处是它们构成了。以下是他们撰写的几种方式:

  • 您可以提供一个enumator 然后另一个
  • 您可以在(T) => U的枚举器上映射 T类型的函数,以获取U
  • 的枚举数
  • 您可以交错两个枚举器
  • 一个iteratee可以留下一些输入供另一个iteratee使用