공식 문서 번역/Coroutines 공식 문서
Coroutines Flow 2편 - Flow 취소하기, Flow 빌더, Flow 중간 연산자
Flow 취소하기 Flow는 Coroutines의 기본적인 협력적인 취소를 따른다. 일반적으로, 취소 가능한 일시중단 함수(delay 같은)에서 Flow가 일시중단될 때 Flow로부터 값을 수집하는 것이 취소될 수 있다. 다음의 예는 Flow가 withTimeoutOrNull 블록에서 실행될 때, Flow가 시간 초과에 따라 어떻게 취소되고 코드 실행이 중지되는지 보여준다 : fun simple(): Flow = flow { for (i in 1..3) { delay(100) println("Emitting $i") emit(i) } } fun main() = runBlocking { withTimeoutOrNull(250) { // Timeout after 250ms simple().collect { ..
Coroutines Flow 1편 - 복수의 값들 표현하기, Flow는 차갑다
일시 중단 함수들은 비동기적으로 단일 값을 반환한다. 그렇다면 어떻게 비동기적으로 계산된 복수의 값들을 반환할 수 있을까? 여기에서 바로 Kotlin의 Flows가 등장한다. 복수의 값들 표현하기 Kotlin에서 복수의 값들은 Collections를 사용해 표현될 수 있다. 예를 들어 3개의 숫자를 가진 List를 반환하는 simple 함수를 가지고, forEach를 사용해 그들을 모두 프린트할 수 있다. fun simple(): List = listOf(1, 2, 3) fun main() { simple().forEach { value -> println(value) } } 📌 전체 코드는 이곳에서 확인할 수 있습니다. 이 코드의 출력은 다음과 같다 : 1 2 3 Sequences 만약 CPU 리소스를..
Coroutine Context와 Dispatcher 5편 - Coroutine Scope
Coroutine Scope Context, 자식 그리고 Job들에 대한 지식을 결합시켜보자. 어플리케이션이 Coroutine이 아닌 생명주기을 가진 객체를 가지고 있다고 가정해보자. 예를 들어, 안드로이드 어플리케이션을 만들고 안드로이드 Activity의 Context 상에서 데이터를 가져오고 업데이트 시키거나, 애니메이션을 실행하는 등의 비동기 작업들을 수행하기 위해서 다양한 Coroutine들을 실행시킬 수 있다. 이 Coroutine들은 Activity가 파괴될 때 메모리 누수를 방지하기 위해 취소되어야 한다. 물론 Context와 Job들을 직접 조작하여 Activity의 Coroutine의 생명주기를 결합시킬 수 있다. 하지만, kotlinx.coroutines 패키지는 CoroutineSco..
Coroutine Context와 Dispatcher 4편 - 부모 Coroutine의 책임, Coroutines에 이름 짓기, Context 요소들 결합하기
부모 Coroutine의 책임 부모 Coroutine은 언제나 자식들이 완료될 때까지 기다린다. 부모는 모든 자식들의 실행을 명시적으로 추적하지 못하고, 그들이 모두 끝날 때까지 기다리기 위해 Job.join을 사용할 필요가 없다. // launch a coroutine to process some kind of incoming request val request = launch { repeat(3) { i -> // launch a few children jobs launch { delay((i + 1) * 200L) // variable delay 200ms, 400ms, 600ms println("Coroutine $i is done") } } println("request: I'm done and..
Coroutine Context와 Dispatcher 3편 - Thread 전환 하기, Context 내부의 Job, Coroutine의 자식들
Thread 전환 하기 다음 코드를 JVM option에 -Dkotlinx.coroutines.debug를 넣어 실행시켜보자(debug 확인). newSingleThreadContext("Ctx1").use { ctx1 -> newSingleThreadContext("Ctx2").use { ctx2 -> runBlocking(ctx1) { log("Started in ctx1") withContext(ctx2) { log("Working in ctx2") } log("Back to ctx1") } } } 📌 전체 코드는 이곳에서 확인할 수 있습니다. 이는 몇가지 새로운 기술들을 보여준다. 하나는 runBlocking을 명시적으로 구체화된 Context와 함께 사용하는 것이고, 다른 하나는 아래 출력 에서..