여러 개의 엔드포인트에서 데이터를 동시에 얻어야 하는 중단 함수를 떠올려보자. 가장 바람직한 방법을 보기 전에 차선책부터 살펴보자.
중단 함수에서 중단 함수를 호출하는 것이 첫 번째 방법이다. 문제는 작업이 동시에 진행되지 않는다는 점이다(하나의 엔드포인트에서 데이터를 얻는 데 1초씩 걸리기 때문에 함수가 끝나는 데 1초 대신 2초가 걸린다).
// 데이터를 동시에 가져오지 않고 순차적으로 가져옴
suspend fun getUserProfile(): UserProfileData {
val user = getUserData() // 1초 후
val notifications = getNotifications() // 1초 후
return UserProfileData(
user = user,
notifications = notifications,
)
}
두 개의 중단 함수를 동시에 실행하려면 각각 async로 래핑해야 한다. 하지만 async는 스코프를 필요로 하며 GlobalScope를 사용하는 건 좋은 방법이 아니다.
// 이렇게 구현하면 안 됨
suspend fun getUserProfile(): UserProfileData {
val user = GlobalScope.async { getUserData() }
val notifications = GlobalScope.async { getNotifications() }
return UserProfileData(
user = user.await(), // 1초 후
notifications = notifications.await(),
)
}
GlobalScope는 그저 EmptyCoroutineContext를 가진 스코프일 뿐이다.
GlobalScope에서 async를 호출하면 부모 코루틴과 아무런 관계가 없다. 이때 async 코루틴은
가장 중요한 결과는 다음과 같다.
따라서 GlobalScope를 사용하는 방법은 좋지 않다. 스코프를 인자로 넘기는 다음 방법을 살펴보자.
// 이렇게 구현하면 안 됨
suspend fun getUserProfile(
scope: CoroutineScope
): UserProfileData {
val user = scope.async { getUserData() }
val notifications = scope.async { getNotifications() }
return UserProfileData(
user = user.await(), // 1초 후
notifications = notifications.await(),
)
}
또는