2013-08-06 13 views
5

Podczas korzystania Playframework, ja czasami do czynienia z taką sytuacją:Użycie Scala Future w Playframework?

def myFunction:Future[String] = { 
    // Do some stuff 
} 

myFunction.onComplete { 
    case Success(myString) => // Du Stuff 
    case Failure(error) => // Error handling 
} 

Ale jak stwierdzono w dokumencie Scala, Future.onComplete zwraca całość. Jak używać tych elementów w trybie Playframework, gdy funkcje Action oczekują na przykład SimpleResult? Jakie są najlepsze praktyki w zakresie obsługi kontraktów futures?

EDYCJA: Powinienem dodać, korzystam z oddziału Play-2.2.x, który sprzedał grę Play Future dla Scala Future.

+0

Interesujący link @ flawian, dzięki. –

Odpowiedz

7

Można użyć Async:

def index = Action{ 
    val myFunction:Future[Option[String]] = // 
    Async{ 
     myFunction.map{ 
     case Some(x) => Ok(x) 
     case None => InternalServerError 
     } 
    } 
} 

zasadzie powiedzieć, że zagrać: Kiedykolwiek myFunction ocenia, zwraca wynik z powrotem do użytkownika. Podejście polega na tym, że zamiast używać wywołania zwrotnego, można użyć map na treści Future, co pozwala na obsługę wyniku.

Wspaniałą częścią jest to, że nadal jest asynchroniczna. W tym sensie, że indeks oceny wątku żądania HTTP nie zostanie zablokowany.

Pewna dokumentacja na nim here.

+0

Jesteś pewien? O ile mi wiadomo Async jest opakowaniem oczekującym 'Future [SimpleResult]' while 'onComplete' zwraca Unit. To nie kompiluje. Powinienem też dodać, że używam Play 2.2.0-M2, który zamienił futures Play na rodzimą Scala Futures. –

+0

Edytował kod, przeprosiny przed – Jatin

1

Play (przynajmniej w 2.1) dodaje metodę extend1, które mogą okazać się przydatne:

def myFunction: Future[String] = ??? 

myFunction.extend1 { 
    case Redeemed(v) => s"Got result string: $v" 
    case Thrown(t) => s"Got throwable: ${t.getMessage}" 
} // : Future[String] 

to chyba lepiej jednak mieć obliczeń, które zawodzą wyraźnie, używając na przykład Option (jak pokazuje Jatin), Either lub scalaz.\/.

Edycja: jak zauważysz, PlayPromise jest przestarzałe w Play 2.2. To trywialne naśladować jego zachowanie z metodami Future, na przykład:

myFunction.map(v => s"Got result string: $v").recover { 
    case t => s"Got throwable: ${t.getMessage}" 
} 

Jeśli chciał odtworzyć składnię extend1 byłoby proste, aby dodać odpowiednie implicits.

+0

Rzeczywiście, w wersjach poprzedzających '2.2' użyłem' .extend1' jednak podpis jest niekompatybilny z 'scala.concurrent.Future'. –

+0

Edytowałem swoją odpowiedź, aby uwzględnić jeden z tych sposobów. Możesz również na przykład utworzyć nową 'Promise', podać ją w bloku' onComplete' i zwrócić jej 'Future'. – Hugh

Powiązane problemy