프로젝트를 진행하던 중, 문제가 맞닥들였다.
문제는 회원가입 / 로그인 기능을 구현에 있었는데 함께 살펴보도록 하자.
위 코드는 Retrofit2 라이브러리를 이용해 회원정보를 서버로 넘기는 메소드이다.
User DTO를 성공적으로 넘겼다면 onResponse 함수가 실행될 것이다.
이 부분만 보면 큰 문제를 느끼지 못 할 것이다.
하지만, 만약 register()를 완료한 후에 실행되어야 할 함수가 먼저 실행되면 어떤 문제가 발생하게 될까?
register() 메서드 안의 코드는 콜백 형식이기 때문에 위 코드처럼 사용하게 된다면 정상적인 로직을 수행할 수 없다.
(본인의 경우 register()를 호출 한 후에 로그인을 완료를 알리는 메서드를 통해 다음 액티비티로 넘어가는 로직을 수행하고자 하였다.)
이 때 사용해야하는 것이 바로 코루틴(Coroutine)이다.
나는 그 중에서도 suspendCancellableCoroutine을 사용하였다.
suspendCancellableCoroutine은 코루틴을 잠시 일시정지시킬 수 있는 함수이다.
따라서 register메서드를 suspend로 형식으로 바꾸고, 안의 로직들을 suspendCancellableCoroutine으로 감싸주면 문제가 해결될 것이다.
코드를 살펴보면 continuation.resume()이라는 함수가 보일 것이다.
저 함수는 일시중지한 코루틴을 다시 깨우는 메소드로, 응답을 완료하였다면 그 다음 코루틴들을 실행하라는 의미이다.
viewModelScope.launch {
// repository를 통해 회원가입 요구(중복 계정일 경우 백엔드에서 처리)
userRepository.register(
User(
user?.id.toString(),
user?.kakaoAccount?.email,
user?.kakaoAccount?.profile?.nickname!!,
LoginType.KAKAO_TALK.name
)
)
Timber.d("Register completed, Trying Signining Kakao Talk ...")
loginCallback?.onSignIn(
LoginType.KAKAO_TALK,
ResultType.SUCCESS
) // 다음 액티비티 실행을 위한 콜백 수행
}
register()를 호출하는 부분을 스코프(Scope)로 감싸면 끝이다.
이렇게 코드를 작성하면, register()를 수행한 후에, 이어서 onSignIn() 메서드가 순차적으로 수행된다.
|
왼쪽은 이전 코드의 로그 결과로, register()가 모두 수행되기도 전에 ViewModel에서 그 다음 작업이 실행된 상황이다.
하지만, 코드를 수정한 오른쪽 결과를 보면, 정상적으로 register()을 수행하고 그 이후 ViewModel의 작업이 수행됨을 볼 수 있다.
이처럼 코루틴(Coroutine)을 적절히 활용하면 코드의 흐름을 컨트롤할 수 있음을 배울 수 있다.
아직 부족한게 많기 때문에 계속해서 공부해나가야 겠다.