본문 바로가기
Android 개발/Coroutine , Flow, Channel

Coroutine suspend 동작에 관한 좋은 예와 잘못된 예 # 비동기

by Developer88 2023. 4. 18.
반응형

오늘은 Coroutine 은 기본적으로 비동기를 기본으로 합니다.

그렇기에 비동기 블록이 suspend 되어서 결과값을 받아서 실행해야 할 경우는,

suspend 함수를 위치시킬 때 생각을 해야 합니다.

그렇지 않으면 예상치 못한 동작을 보게되는데요.

 

오늘은 suspend 함수를 이용해서 Coroutine을 잘 사용한 예와 잘못 사용한 예를 점검해 보겠습니다.

 

1. suspend 가 제대로 동작하지 않는 잘못된 케이스

우선은 코드를 보도록 하겠습니다.

아래에서 launch 블록바깥에 결과를 얻어서, print 하는 것이 의도인데요.

실제로 실행해 보면, result에 값이 담기기 전에 지나쳐 버립니다.

 

suspend fun fetchData(): String {
    delay(2000)
    return "data"
}

fun CoroutineScope.processData() {
    var result: String
    launch {
        result = fetchData()
    }
    println("result: $result")
}

fun main() = runBlocking {
    processData()
    println("finished")
}

 

 

실행해 보면 다음과 같이 나오는 것을 볼 수 있습니다.

 

 

2. suspend 가 제대로 동작하는 케이스

가장 쉽게 위의 문제를 해결하는 가장 쉬운 방법 중 하나는,

값을 기다려야 하는 코드를 다음과 같이 하나의 블록안에 같이 코드를 넣는 것 입니다.

이 때 잊지 말아야 할 것은 suspend 키워드가 들어간 함수여야 한다는 것이 중요합니다.

 

이 코드만 보면 너무나 쉬워서, 당연히 이렇게 하지 않을까 하지만,

실제로 앱을 만들면서 긴 코드를 작성하다보면 이런 간단한 것을 이해하지 못하고 하다보면,

왜 suspend가 동작하지 않는 것인지 이해가 안될 수 있습니다.

 

suspend fun fetchData(): String {
    delay(2000) 
    return "Hello World from Server"
}

fun CoroutineScope.processData() {
    var result: String
    launch {
        result = fetchData()
        println("result: $result")
    }
}

fun main() = runBlocking {
    processData()
    println("finished")
}

 

 

실행해 보면 다음과 같이 잘 나오는 것을 볼 수 있습니다.

finished 가 먼저 찍혀 나오는 것을 볼 수 있는데요.

이렇게, 같은 CoroutineBlock 안에 있어서 suspend 되는 suspend 함수가 아니라면,

비동기 코드이기 때문에, 2초간 delay되는 processData보다 finished가 먼저 실행되는 것 입니다.

 

 

3. 정리

사실 Coroutine에는 값을 기다려서 실행을 suspend 하는 API들이 이미 존재하기는 합니다.

하지만, 꼭 그렇게 하지 않더라도, 

suspend 함수와 블록의 위치만을 잘 조절하기만 해도, 

원하는 순서로 코드의 실행을 조절할 수 있습니다.

 

728x90

댓글