我是Scala和Play!的新手,但是在使用Django和Python以及编程方面拥有合理的构建webapps的经验。
我一直在努力练习提高自己的理解力 - 只需从数据库中提取一些记录并将其作为JSON数组输出。我正在尝试使用Enumarator / Iteratee功能来执行此操作。
我的代码如下:
TestObjectController.scala:
def index = Action {
db.withConnection { conn=>
val stmt = conn.createStatement()
val result = stmt.executeQuery("select * from datatable")
logger.debug(result.toString)
val resultEnum:Enumerator[TestDataObject] = Enumerator.generateM {
logger.debug("called enumerator")
result.next() match {
case true =>
val obj = TestDataObject(result.getString("name"), result.getString("object_type"),
result.getString("quantity").toInt, result.getString("cost").toFloat)
logger.info(obj.toJsonString)
Future(Some(obj))
case false =>
logger.warn("reached end of iteration")
stmt.close()
null
}
}
val consume:Iteratee[TestDataObject,Seq[TestDataObject]] = {
Iteratee.fold[TestDataObject,Seq[TestDataObject]](Seq.empty[TestDataObject]) { (result,chunk) => result :+ chunk }
}
val newIteree = Iteratee.flatten(resultEnum(consume))
val eventuallyResult:Future[Seq[TestDataObject]] = newIteree.run
eventuallyResult.onSuccess { case x=> println(x)}
Ok("")
}
}
TestDataObject.scala:
package models
case class TestDataObject (name: String, objtype: String, quantity: Int, cost: Float){
def toJsonString: String = {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
mapper.writeValueAsString(this)
}
}
我有两个主要问题:
如何从Enumerator回调中发出输入完成的信号?文档说“这个方法需要一个回调函数e:=> Future [Option [E]],每次应用这个Enumerator的iteratee时都会调用它来准备接受一些输入。”但是我无法通过任何我发现的EOF,因为它是错误的类型。将它包装在未来并没有帮助,但本能地我不确定这是正确的方法。
如何从控制器视图中返回Future的最终结果?我的理解是,我实际上需要暂停主线程等待子线程完成,但我见过的唯一例子,我在未来的类中找到的只是onSuccess回调 - 但我怎么能那么从视图中返回? Iteratee.run是否阻塞,直到所有输入都被消耗?
还有几个子问题,以帮助我理解:
非常感谢你提出任何答案,我认为我已经掌握了这个问题,但显然还没有!
答案 0 :(得分:0)
如何从Enumerator回调中发出输入完成信号?
您返回Future(None)
。
如何从控制器视图中返回Future的最终结果?
您可以使用Action.async
(doc):
def index = Action.async {
db.withConnection { conn=>
...
val eventuallyResult:Future[Seq[TestDataObject]] = newIteree.run
eventuallyResult map { data =>
OK(...)
}
}
}
为什么我的对象已经在未来时需要将我的对象包装在Some()中? Some()究竟代表什么?
Future
表示获取下一个元素的(可能是异步的)处理。 Option
代表下一个元素的可用性:Some(x)
如果另一个元素可用,None
如果枚举完成。