2013-02-24 38 views
10

Tôi đang sử dụng:scala, vui chơi, tương lai: kết quả kết hợp từ nhiều tương lai

  • Scala 2.10
  • Chơi 2,1

Hiện nay, tôi đang sử dụng lớp Future từ scala.concurrent._, nhưng tôi đang mở để thử một API khác.

Tôi gặp sự cố khi kết hợp các kết quả của nhiều tương lai vào một Danh sách duy nhất [(Chuỗi, Chuỗi)].

Phương pháp Controller sau trả thành công kết quả của một tương lai duy nhất để một mẫu 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)]()))) 
      } 
     } 
     }) 
    } 

Phương pháp getSearchResult(String, Int) thực hiện một cuộc gọi API dịch vụ web và trả về một tương lai [play.api.libs.ws .Phản ứng]. Phương thức getAuthors(String, List[(String, String)]) trả về một List [(String, String)] thành mẫu HTML.

Bây giờ, tôi đang cố gọi getSearchResult(String, Int) trong vòng lặp for để nhận một số nội dung phản hồi. Sau đây sẽ cung cấp cho một ý tưởng về những gì tôi đang cố gắng để làm, nhưng tôi nhận được một lỗi thời gian biên dịch:

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)) 
     } 
     }) 
    } 

loại không phù hợp; tìm thấy: scala.collection.immutable.IndexedSeq [scala.concurrent.Future [Danh sách [(String, String)]]] yêu cầu: Danh sách [(String, String)]

Làm thế nào tôi có thể lập bản đồ các phản ứng của nhiều Future đối tượng cho một đơn Result?

Trả lời

9

Tạo tương lai được parametrized bởi Danh sách hoặc Bộ sưu tập khác của loại Kết quả.

Từ here:

Trong Chơi 1 bạn có thể làm điều này:

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 

Trong Chơi 2 ít trực tiếp:

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

Hm, liên kết giúp. Tôi đã thử cách tiếp cận được đăng bởi Julian Richard-Foy: 'val httpResponses = Promise.sequence (Danh sách (remoteCall1, remoteCall2))'. Điều này đã cho phép tôi để có được một thể hiện của 'Tương lai [IndexedSeq [Response]]', đó là tuyệt vời. Tuy nhiên, tôi vẫn đang cố gắng ánh xạ danh sách Câu trả lời vào một danh sách duy nhất của [(Chuỗi, Chuỗi)]. Ngay bây giờ, nó chỉ lập bản đồ kết quả của tương lai đầu tiên –

+0

@DavidKaczynski Trong ứng dụng Java của chúng tôi, chúng ta sẽ viết một thư viện Promise nhỏ và tạo ra phương thức 'Promise.whenAll (Promise ...)'. Vì vậy, trong nghiên cứu câu hỏi của bạn, tôi đã thử Googling cho các công cụ như, "scala chơi lời hứa từ bộ sưu tập," "... từ danh sách," vv. Như một phương pháp tôi thực sự mong đợi sẽ rất chuẩn. Xem thêm: https://github.com/playframework/Play20/pull/677 – djechlin

+0

Khi kiểm tra kỹ hơn, phương pháp tôi đã mô tả trong bình luận đầu tiên của tôi đã hoạt động. Tôi đã có một "lỗi" khác mà chỉ trả lại kết quả từ một tương lai. Một khi tôi tạo ra một Promise từ một chuỗi ** Futures ** khác nhau, tôi đã nhận được tất cả các phản hồi trong một Future. Công cụ tuyệt vời! –

Các vấn đề liên quan