2015-01-27 9 views
0

재생 프레임 워크 내에서 스칼라즈의 IO 모나드를 사용하는 작은 예제를 작성했습니다. 예상대로 작동 아래의 예 : 재생 ActionBuilder의 사용이 약간 덜 자세한 API이 발생할 수 있습니다 경우ActionBuilder가 [결과] 대신 [결과]를 받음 [결과]

object IOAction { 
    def apply(action:IO[Result]):Result = action.unsafePerformIO 
} 

class ExampleController extends Controller { 
    val now:IO[DateTime] = IO { DateTime.now } 

    def index = Action { request => 
    IOAction { 
     now.map { dateTime => Ok(views.html.index(dateTime)) } 
    } 
    } 
} 

가 궁금하네요. 이상적으로, 내가 쓰고 싶은 다음 invokeBlock 기능은 Future[Result] 유형에 고정하는 것 때문에 내가 붙어있어

class ExampleController extends Controller { 
    val now:IO[DateTime] = IO { DateTime.now } 

    def index = IOAction { request => 
    now.map { dateTime => Ok(views.html.index(dateTime)) } 
    } 
} 

.

def invokeBlock[A](request: R[A], block: P[A] => Future[Result]): Future[Result] 

사람이 IOAction 액션처럼 동일하게 동작 해결 방법을 알고 있나요 (예. 선택적인 요청 매개 변수와 몸 파서)?

+0

play-2.0이나 play-2.3을 사용하지 않습니까? – phadej

+1

Play 2.3.7을 사용하고 있습니다. – user3459840

답변

2

하지 후자의 예를 작업, 당신은 IOAction를 재정의해야하는 경우 :

object IOAction { 
    def apply(io: Request[AnyContent] => IO[Result]): Action[AnyContent] = 
    Action { (request: Request[AnyContent]) => io(request).unsafePerformIO } 
} 

그리고 Controller 객체에서 당신이 할 수있는을

def foo(): Handler = IOAction { request => 
    Ok("foo").point[IO] 
} 

즉, Future은 비동기 (IO) 계산이며, IO은 동기식입니다. 따라서 IO에서 Future으로 변환하는 것이 쉽습니다.


IOActionBuilder의 조합은 운동을 정말하지 않습니다. ActionBuilderIO을 염두에두고 작성되었습니다.

final def io(block: => Result): Action[AnyContent] 
final def io(block R[AnyContent] => Result): Action[AnyContent] 

이 그럼 당신은 정의 할 수 있습니다 :

object IOAction extends IOActionBuilder[Request] { /* ... */ } 

을 그리고로 사용 : 그것은

final def apply(block: ⇒ Result): Action[AnyContent] 
final def apply(block: (R[AnyContent]) ⇒ Result): Action[AnyContent] 
final def async(block: ⇒ Future[Result]): Action[AnyContent] 
final def async(block: R[AnyContent]) ⇒ Future[Result]): Action[AnyContent] 

당신은 특성이 ActionBuilder[R]을 확장하고 제공 할 수있다는 말을

def foo = IOAction.io { request => 
    Ok("foo").point[IO] 
} 

이것은 거의 우리가 먼저 정의한 것과 정확히 똑같습니다. 그렇게 직접적으로는 아닙니다. ActionComposition.scala 관심에서


기본 동작를 제공하지 않는, 구성하는 행동입니다.

+0

요청 매개 변수에도 액세스하려는 경우 첫 번째 솔루션이 작동하지 않습니다. 두 번째 솔루션은 ActionBuilder와 함께 IOAction을 사용하기 때문에 작동하지 않습니다. IOAction의 'io' 매개 변수는 Action 유형이어야합니다 [A] 나는 추측한다. 참조 : https://github.com/mariussoutier/PlayBasics/blob/master/play-2.2-migration/app/controllers/ActionComposition.scala – user3459840