2013-02-24 79 views
10

我使用来自多个期货相结合的结果:阶,发挥期货:

  • 斯卡拉2.10
  • 播放2.1

目前,我正在使用从scala.concurrent._Future类,但我可以尝试另一种API。

我无法将多个期货的结果合并成一个List [(String,String)]。

以下Controller方法成功单个未来结果返回给HTML模板:

def test = Action { implicit request => 
    queryForm.bindFromRequest.fold(
     formWithErrors => Ok("Error!"), 
     query => { 
     Async { 
      getSearchResponse(query, 0).map { response => 
      Ok(views.html.form(queryForm, 
       getAuthors(response.body, List[(String, String)]()))) 
      } 
     } 
     }) 
    } 

getSearchResult(String, Int)执行web服务的API调用,并返回一个未来[play.api.libs.ws的方法。响应]。方法getAuthors(String, List[(String, String)])向HTML模板返回一个List [(String,String)]。

现在,我想在for循环中调用getSearchResult(String, Int)以获得多个Response实体。下面应该给的什么,我试图做一个想法,但我得到一个编译时错误:

def test = Action { implicit request => 
    queryForm.bindFromRequest.fold(
     formWithErrors => Ok("Error!"), 
     query => { 
     Async { 
      val authors = for (i <- 0 to 100; if i % 10 == 0) yield { 
      getSearchResponse(query, i) 
      }.map { response => 
      getAuthors(response.body, List[(String, String)]()) 
      } 

      Ok(views.html.form(queryForm, authors)) 
     } 
     }) 
    } 

类型不匹配;发现:scala.collection.immutable.IndexedSeq [scala.concurrent.Future [列表[(字符串,字符串)]]]要求:列表[(字符串,字符串)]

我怎么能映射的几个答复Future对象到单个Result

回答

9

创建一个由列表或结果类型的其他集合参数化的Future。

here

在播放1,你可以这样做:

F.Promise<List<WS.HttpResponse>> promises = F.Promise.waitAll(remoteCall1, remoteCall2, remoteCall3); 

    // where remoteCall1..3 are promises 

    List<WS.HttpResponse> httpResponses = await(promises); // request gets suspended here 

在播放2不那么直接:

val httpResponses = for { 
    result1 <- remoteCall1 
    result2 <- remoteCall2 
} yield List(result1, result2) 
+0

嗯,那个链接帮助。我尝试了Julian Richard-Foy发布的方法:'val httpResponses = Promise.sequence(List(remoteCall1,remoteCall2))'。这让我得到了一个'Future [IndexedSeq [Response]]'的实例,这非常棒。但是,我仍然试图将响应列表映射到[(String,String)]的单个列表中。现在,它只映射第一个Future的结果 – 2013-02-24 02:17:52

+0

@DavidKaczynski在我的Java应用程序中,我们写了一个小的Promise库并创建了一个'Promise.whenAll(Promise ...)'方法。因此,在研究你的问题时,我尝试了Google的搜索功能,例如“scala玩游戏承诺”,“...从列表中删除”等等。我真的希望这种方法非常标准。另请参阅:https://github.com/playframework/Play20/pull/677 – djechlin 2013-02-24 02:49:06

+0

经过进一步检查,我在第一条评论中描述的方法奏效。我有另一个“错误”,只是从一个未来返回结果。一旦我从一系列不同的**期货中创造了一个承诺,我就在单一的未来中获得了所有的答复。棒极了! – 2013-02-24 20:31:17