2012-08-05 12 views
4

我用枚举器模式来检索一些鸣叫每一秒与WS.url通过Play2/Scala进行定期WS调用以提供Enumerator的最佳方式?

Enumerator.fromCallback[String](() => 
     Promise.timeout(WS.url("http://search.twitter.com/search.json?q="+query+"&rpp=1").get().map { response => 
      val tweets = response.json \\ "text" 
      tweets match { 
       case Nil => "Nothing found!" 
       case head :: tail => query + " : " + head.as[String] 
      } 
     }.map(Some.apply).value.get, 1000 milliseconds) 
) 

我的是问题是,

Enumerator.fromCallback[String]() 

正在等待

Promise[Option[String]] 

由于WS。 url(...)。get返回Promise,并且当我使用Promise.timeout每秒重新​​启动呼叫时,

我有一个

Promise[Promise[Option[String]]] 

所以我必须用value.get具有良好的类型,所以它似乎并不为异步方面很干净。

此代码有效,但我的问题是:有没有更好的方法,更优雅,实现这一目标? 我可以轻松地从另一个承诺和Promise.timeout轻松获得承诺吗?

谢谢:)

+1

出了问题,你应该看看Twitter流API。我们首先在TT Search上启动了拒绝请求,并以流媒体API结束:https://dev.twitter.com/docs/streaming-apis – iwalktheline 2012-08-07 14:44:06

回答

4

Promise是一个单子,一般当你发现自己要在某处坚持一个flatMap嵌套的单子。你的情况是这样的应该工作:

import akka.util.duration._ 
import play.api.libs.concurrent._ 
import play.api.libs.iteratee._ 
import play.api.libs.ws._ 

val query = "test" 
val url = WS.url("http://search.twitter.com/search.json?q=" + query + "&rpp=1") 

val tweets = Enumerator.fromCallback[String](() => 
    Promise.timeout(url.get, 1000 milliseconds).flatMap(_.map { response => 
    (response.json \\ "text") match { 
     case Nil => "Nothing found!" 
     case head :: _ => query + " : " + head.as[String] 
    } 
    }.map(Some.apply)) 
) 

我亲自写的更是这样的:

val tweets = Enumerator.fromCallback[String](() => 
    Promise.timeout(url.get, 1000 milliseconds).flatMap(_.map(
    _.json.\\("text").headOption.map(query + " " + _.as[String]) 
)) 
) 

而不是与"Nothing found!"消息做文章,而是取决于你在做什么这可能不合适。

+0

非常感谢您的帮助! – Loic 2012-08-05 16:44:25

相关问题