Scala播放“枚举器”:推还是拉?

Scala播放“枚举器”:推还是拉?,scala,playframework,iterate,Scala,Playframework,Iterate,我真的很难理解Play的Iteratees和Enumerators的基本用途 我读过 我读了这篇文章,发现它不是依赖于拉式模型,比如InputStream,而是使用了推式模型 迭代对象是一个有趣的野兽——一方面,它将数据“推”到处理程序,而不是依赖处理程序来拉取数据,因此具有更好的性能。另一方面,它允许处理程序控制流何时停止 但是Play在Iteratee上的文档说 或者更一般地使用枚举器.fromStream枚举java.io.InputStream。需要注意的是,在应用此枚举数的迭

我真的很难理解Play的
Iteratee
s和
Enumerator
s的基本用途

我读过

我读了这篇文章,发现它不是依赖于拉式模型,比如
InputStream
,而是使用了推式模型

迭代对象是一个有趣的野兽——一方面,它将数据“推”到处理程序,而不是依赖处理程序来拉取数据,因此具有更好的性能。另一方面,它允许处理程序控制流何时停止

但是Play在Iteratee上的文档说

或者更一般地使用
枚举器.fromStream
枚举
java.io.InputStream
。需要注意的是,在应用此枚举数的迭代者准备接受更多输入之前,不会读取输入

等等……发生了什么事


数据是由
枚举器推送的还是由
迭代对象拉取的?(即,由谁决定何时计算更多数据)

两者。它对于流的两端都是完全无阻塞的

Enumerator
Iteratee
准备好接收数据之前不会推送任何数据,并且在
Iteratee
发出准备接收更多数据的信号之前不会推送任何更多数据。同时,
枚举器
可能需要推送数据的时间。这两个进程都不会阻止另一个进程

在迭代对象上,此方法对于理解其工作原理至关重要:

abstract def fold[B](folder: (Step[E, A]) ⇒ Future[B])(implicit ec: ExecutionContext): Future[B]
这是
Iteratee
中唯一的抽象方法,也是唯一必须实现的方法。其余的所有方法都是根据
折叠定义的。当
枚举器
应用于
迭代对象
时,它调用此方法,提供有效回调的
文件夹
。一旦
Iteratee
准备就绪,它将调用
文件夹
提供它当前所处的状态,
Cont
如果它可以接收更多数据,
Done
如果它不需要更多数据,或者
Error
如果出现问题。由于
文件夹
返回一个
未来
,因此如果
迭代对象
处于
继续
状态,则需要提供进一步输入的时间可能会更长