来自Twitter Future的Play Framework返回结果

时间:2014-10-21 09:21:20

标签: scala playframework-2.0

我有下一个代码,当number为0时返回true,否则为异常

  import com.twitter.util.Future 

  def compute(x: Int): Future[Boolean] = {
     if (x == 0) {
       Future.value(true)
     } else {
       Future.value(new Exception("Invalid number"))
     }
  }  

我的控制器用于处理此代码:

 object MyController extends Controller {

   def get(x: Int) = Actrion {
     compute(x).flatMap {
       case x: Boolean => Ok(views.html.ok("ok"))
       case _ => NotFound 
     }
   }  
 }

但是当我运行此代码时,我得到type mismatch; found : play.api.mvc.Result required: com.twitter.util.Future[?]

如何从Future中提取值并将结果传递给响应?

2 个答案:

答案 0 :(得分:1)

Play使用Scala期货,而非Twitter期货。如果你必须使用Twitter的未来,你必须转换它。以下代码取自Akka feature request

import scala.concurrent.{Future, Promise}
import com.twitter.util.{Future => TwitterFuture, Throw, Return}

def fromTwitter[A](twitterFuture: TwitterFuture[A]): Future[A] = {
  val promise = Promise[A]()
  twitterFuture respond {
    case Return(a) => promise success a
    case Throw(e) => promise failure e
  }
  promise.future
}

然后在你的控制器中使用它:

object MyController extends Controller {true
  def get(x: Int) = Action.async {
    fromTwitter(compute(x)).map { _ =>
      Ok(views.html.ok("ok")) 
    }.recover { case e =>
      NotFound
    }
  }  
}

你的case语句也没有意义,输入布尔值的Future总是会产生布尔值。如果将来失败,您可以使用recoverrecoverWithfallbackTo

答案 1 :(得分:-2)

根据Future doc错误是由于flatMap定义引起的。我宁愿使用mappoll方法。

此外,我建议将scala.concurrent.Future与Action.async一起使用,如下所示:

def index = Action.async {
  val futureInt = scala.concurrent.Future { intensiveComputation() }
  futureInt.map(i => Ok("Got result: " + i))
}

可以找到更多信息here