首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >什么是等同于Play框架的Enumerator.fromCallback的scalaz-stream

什么是等同于Play框架的Enumerator.fromCallback的scalaz-stream
EN

Stack Overflow用户
提问于 2014-04-13 01:51:10
回答 1查看 463关注 0票数 5

Play框架的迭代库定义了一个方法Enumerator.fromCallback,它允许基于未来的结果生成元素:

http://www.playframework.com/documentation/2.2.x/Enumerators

代码语言:javascript
运行
复制
def fromCallback[E](
  retriever: () => Future[Option[E]],
  onComplete: () => Unit = () => (),
  onError: (String, Input[E]) => Unit = (_: String, _: Input[E]) => ()
): Enumerator[E]

您可以在这里看到一个很好的示例,该示例用于从Web服务交付分页结果:

http://engineering.klout.com/2013/01/iteratees-in-big-data-at-klout/

代码语言:javascript
运行
复制
def pagingEnumerator(url:String):Enumerator[JsValue]={
  var maybeNextUrl = Some(url) //Next url to fetch
  Enumerator.fromCallback[JsValue] ( retriever = {
    val maybeResponsePromise =
      maybeNextUrl map { nextUrl=>  
        WS.url(nextUrl).get.map { reponse =>
          val json = response.json
          maybeNextUrl = (json \ "next_url").asOpt[String]
          val code = response.status //Potential error handling here
          json
        }   
      }

    /* maybeResponsePromise will be an Option[Promise[JsValue]].
     * Need to 'flip' it, to make it a Promise[Option[JsValue]] to
     * conform to the fromCallback constraints */
    maybeResponsePromise match {
      case Some(responsePromise) => responsePromise map Some.apply
      case None => PlayPromise pure None
    }
  })
}

做同样的事情,等价的scalaz-stream代码是什么?我非常确定可以使用Process.emitProcess.await或者Process.eval来完成这项工作,但我希望看到一个完善的示例。这可能还需要将scala Future提升为scalaz任务,这里有一个答案:

Convert scala 2.10 future to scalaz.concurrent.Future // Task

如果它让事情变得更简单,我们可以忽略scala Future vs scalaz Task位,并假设我们有一个Task。

EN

回答 1

Stack Overflow用户

发布于 2014-04-13 02:47:07

要从scala.concurrent.Future获取scalaz.concurrent.Task,你可以使用Task.async,当你手中有任务时,你可以这样做:

代码语言:javascript
运行
复制
  import java.util.concurrent.atomic.AtomicInteger
  import scalaz.concurrent.Task
  import scalaz.stream.Process.End
  import scalaz.stream._

  val cnt = new AtomicInteger(0)

  val task: Task[String] = Task {
    if (cnt.incrementAndGet() <= 10) s"Task ${cnt.get}" else throw End
  }

  Process.repeatEval(task).runLog.run.foreach(println)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23034026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档