💻 프로그래밍

[🔥Coroutine] #4 suspend, Job 간단하게 살펴보기

콩드로이드 2022. 11. 30. 22:41

시작 전 복습 한 마디

루틴이 쓰이는 모든 곳에는 CoroutineScope가 있습니다

CoroutineScope는 CoroutineContext(코루틴을 처리하기위한 정보)를 가지고 있습니다 

 


suspend 

코루틴 내에서만 함수를 호출하지 않고, 코드의 일부를 함수로 분리하려면 suspend 키워드를 사용

suspend가 붙은 함수를 사용하려면

1. 그 함수가 suspend이거나

2. CoroutineBuilder를 통해 코루틴을 만들어야한다

suspend fun showName(){
    println("showName")
    delay(500L)
    println("My name is Kong")
}

suspend fun showAge(){
    println("showAge")
    delay(1000L)
    println("secret")
}

fun main() = runBlocking<Unit> {
    launch {
    	showName()
    }
	
    launch {
    	showAge()
    }
}

 

결과 

 

만약, 코루틴 빌더(launch, async..)를 suspend에서 호출한다면? 

에러가 발생합니다 왜냐하면

⚠️ CoroutineBuilder는 CoroutineScope내에서만 호출해야합니다

 


CoroutineScope 생성

스코프 빌더(coroutineScope)를 사용합니다

 

runBlocking은 현재 Thread를 멈추게 하지만, coroutineScope는 멈추게 하지 않고, 호출한쪽이 suspend 됩니다

 


Job

코루틴의 상태를 가지고 있고, 이를  제어합니다 (말 그대로 '작업')

launch는 Job을 반환하게 됩니다  

다른 함수들은 2022.08.30 - [💻 프로그래밍] - [🔥Coroutine] # 1 Coroutine을 배워봅시다 참조해주세요 :)

✅ join()

-  launch가 종료될때까지 기다릴 수 있습니다 

suspend fun Test() = coroutineScope {
    val job = launch {
        println("나 끝날때까지 기다려줘")
        delay(1000L)
        println("밑에 다른 애들 먼저 출력하면 안돼")
    }
    job.join()

    launch {
        println("내가 더 빨리 출력될래ㅠㅠ")
    }
}

fun main() = runBlocking<Unit> {
    Test()
}

 

결과

더보기
애석하게도,, job이 끝날때까지 기다려줘요

 

✅ cancel()

- job을 취소할 수 있습니다 

suspend fun Test() = coroutineScope {
    val job1 = launch {
        println("다들 강당으로 모여!!!")
        delay(1000L)
        println("1번!")
    }

    val job2= launch {
        println("2번!!")
        delay(500L)
        println("번호끝!")
    }

    delay(1000L)
    job1.cancel()
    job2.cancel()
    println("1번 어디갔어😡")
}

 

결과

 

이런 불상사를 막기위해 취소가능한 블록으로 만들 수 있습니다

✅ withContext(NonCancellable)

suspend fun Test() = coroutineScope {
    val job1 = launch {
        withContext(NonCancellable) {
            println("다들 강당으로 모여!!!")
            delay(1000L)
            println("1번!")
        }
    }

    val job2 = launch {
        withContext(NonCancellable) {
            println("2번!!")
            delay(500L)
            println("번호끝!")
        }
    }

    delay(1000L)
    job1.cancel()
    job2.cancel()
    println("1번 왜 늦었어😡")
}

 

결과

더보기
그래도 도착이라도 한 1번입니다 :)