我真的无法理解Play的Iteratee
和Enumerator
的基本目的。
我读过
我读了这个answer,发现它不是依赖拉动模型,而是InputStream
,而是使用推模型。
Iteratees是一个有趣的野兽 - 一方面,它“将”数据“推送”到处理程序,而不是依靠处理程序来提取数据,因此具有更好的性能。另一方面,它允许处理程序控制何时应该停止流程。
但是,然后Play的Iteratee
s文档说
或更一般地使用
java.io.InputStream
枚举Enumerator.fromStream
。重要的是要注意,在应用此枚举器的iteratee准备好接受更多输入之前,不会读取输入。
等等......所以发生了什么事?
数据是由Enumerator
推送还是由Iteratee
提取的? (即谁决定何时计算更多数据)
答案 0 :(得分:3)
两者。它对于流的两端完全没有阻塞。
Enumerator
在Iteratee
准备接收数据之前不会推送任何数据,并且它不会推送任何更多数据,直到Iteratee
发出信号为止准备好了。与此同时,Enumerator
只要想要推送数据就可以。这两个过程都不会阻止另一个过程。
此方法在Iteratee
上对于了解其工作原理至关重要:
abstract def fold[B](folder: (Step[E, A]) ⇒ Future[B])(implicit ec: ExecutionContext): Future[B]
这是Iteratee
中唯一必须实现的抽象方法。所有其他方法都是根据fold
定义的。当Enumerator
应用于Iteratee
时,它会调用此方法,提供有效回调的folder
。在Iteratee
准备就绪后,它会调用folder
提供其当前所处的状态,Cont
是否可以接收更多数据,Done
如果它不需要任何更多,或Error
如果出现问题。由于folder
会返回Future
,因此只要Iteratee
处于Cont
状态,就需要提供更多输入。