Jak zaobserwowaliśmy, jako użytkownika końcowego (to znaczy w przeglądarce), nie będzie widocznej różnicy pomiędzy swoimi dwoma fragmentów kodu.
Różnica polega na tym, że w przypadku "sync"
cały wątek/aktor/cokolwiek-to-to, który obsługuje twoją prośbę w Play został skrępowany, kręcąc kciukami, czekając na zakończenie Thread.sleep
.
W przypadku "async"
Natomiast funkcja manipulacja rzeczywiście uruchomić a tym samym zasobem, który go prowadził (gwint/aktor/cokolwiek) uwalnia się robić inne rzeczy. Kiedy ostatecznie zakończy się Future
, może zakończyć pracę.
Najlepszym sposobem, aby zobaczyć różnicę jest posypać w kilku wpisach dziennika:
def intensiveComputation(): Int = {
Logger.info("Sleeping")
Thread.sleep(5000)
Logger.info("Woke up")
return 1
}
def testPromiseSync() = Action {
val result = Ok("sync" + intensiveComputation())
Logger.info("returning to Play")
result
}
def testPromiseAsync = Action.async {
val futureint = scala.concurrent.Future { intensiveComputation() }
val f = futureint.map(i => Ok("async" + i))
Logger.info("returning to Play")
f
}
Kiedy trafiliśmy punkt końcowy sync
, widzimy:
2014-05-14 17:23:39,359 [info] application - Sleeping
2014-05-14 17:23:44,359 [info] application - Woke up
2014-05-14 17:23:44,359 [info] application - returning to Play
A async
:
2014-05-14 17:24:23,376 [info] application - Sleeping
2014-05-14 17:24:23,376 [info] application - returning to Play
2014-05-14 17:24:28,376 [info] application - Woke up
Dzięki zatrudnieniu Action.async
zwolniono Pla y, aby obsłużyć więcej żądań "naraz", zachowując niezmienione wrażenia użytkownika końcowego.
Jesteś zbyt szybki. Dobra odpowiedź. – goral
"... ** cała nić/aktor/cokolwiek-to jest, że obsługuje twoją prośbę w Play została przywiązana **, kręcąc kciukami, czekając aż Thread.sleep skończy." trochę mylące dla mnie. Ponieważ akcje w grze są domyślnie asynchroniczne, a obsługa wątków ** - żądanie nie jest blokowane. – srzhio