2013-11-27 3 views
1

스칼라에 대해 매우 신입생입니다. Play에서 Instagram API에 액세스하려고합니다! 스칼라.재생! 비동기 웹 요청으로 프레임 워크 구성하기

def authenticate = Action { 
request => 
    request.getQueryString("code").map { 
    code => 
     WS.url("https://api.instagram.com/oauth/access_token") 
     .post(
     Map("client_id" -> Seq(KEY.key), "client_secret" -> Seq(KEY.secret), "grant_type" -> Seq("authorization_code"), 
      "redirect_uri" -> Seq("http://dev.my.playapp:9000/auth/instagram"), "code" -> Seq(code)) 
    ) onComplete { 
     case Success(result) => Redirect(controllers.routes.Application.instaline).withSession("token" -> (result.json \ "access_token").as[String]) 
     case Failure(e) => throw e 
     } 
    } 
Redirect(controllers.routes.Application.index) 

}

응용 프로그램이 실행되면, 마지막 리디렉션 전에 성공의 경우 재 발생합니다. 제발 말해줘, 어떻게 피하십시오. 또한, 제 코드에있는 나쁜 습관에 대해 알려주십시오.

+0

완료 대기 위해 기다리고 있습니다 동반자 객체를 사용해보십시오 : Await.ready ($ futurevar, Duration.Inf) –

+1

을 절대로하지, 지금까지 플레이 응용 프로그램에 Await.ready, Await.result 또는 Await.anything를 사용 . 교착 상태와 모든 종류의 다른 것들에 빠지게 될 것입니다. –

답변

5

Play에서는 결과를 보내지 만 결과는 보내지 않습니다. onComplete 메서드는 무언가를 수행하지만 아무 것도 반환하지 않는 메서드를 연결합니다 (반환 값은 Unit, 즉 void 임). 그 콜백을 첨부 한 후, 마지막 행에 Redirect을 리턴합니다. 이는 원하지 않는 것입니다. 대신 당신은 map에 WS 호출에서 돌아와 미래를 되돌아보고 싶습니다. 그리고 Play에서 미래를 되돌리려면 Action.async 빌더를 사용해야합니다. 예 :

def authenticate = Action.async { request => 

    request.getQueryString("code").map { code => 

    WS.url("https://api.instagram.com/oauth/access_token").post(
     Map(
     "client_id" -> Seq(KEY.key), 
     "client_secret" -> Seq(KEY.secret), 
     "grant_type" -> Seq("authorization_code"), 
     "redirect_uri" -> Seq("http://dev.my.playapp:9000/auth/instagram"), 
     "code" -> Seq(code) 
    ) 
    ).map { result => 

     Redirect(controllers.routes.Application.instaline) 
     .withSession("token" -> (result.json \ "access_token").as[String]) 

    } 
    }.getOrElse { 
    Future.successful(Redirect(controllers.routes.Application.index)) 
    } 
}