我真的很难理解Play的IterateeEnumerator的基本目的。

我读了

  • Understand Play2 Iteratees for Normal Humans
  • Iteratees
  • Enumerators

  • 我阅读此answer来发现,它没有像InputStream那样依赖于拉模型,而是使用了推模型。

    迭代器是一种有趣的野兽-一方面,它将数据“推送”到处理程序,而不是依赖处理程序提取数据,因此具有更好的性能。另一方面,它允许处理程序控制何时应停止流。

    但是后来Play关于Iteratee的文档说

    或更一般而言,使用java.io.InputStream枚举Enumerator.fromStream。重要的是要注意,在应用此枚举器的迭代器准备接收更多输入之前,不会读取输入。

    等待....那是怎么回事?

    数据是由Enumerator推送还是由Iteratee提取? (即由谁来决定何时计算更多数据)

    最佳答案

    都。对于流的两端,它是完全不阻塞的。

    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状态,则可能需要花费更多时间才能提供进一步的输入。

    09-26 12:08