Hanbit the Developer

Kotlin Documentation | Coroutines and channels - tutorial 본문

Mobile/Kotlin

Kotlin Documentation | Coroutines and channels - tutorial

hanbikan 2023. 5. 24. 16:56

Kotlin Documentation 시리즈에 대해

Category: Official libraries - Coroutines

문서 링크: https://kotlinlang.org/docs/coroutines-and-channels.html


Concurrency

async: 새 코루틴을 실행하고 Deferred 객체(a.k.a Future or Promise)를 반환한다.

interface Deferred<out T> : Job

launch: 새 코루틴을 실행하고 Job 객체를 반환한다. Job 객체를 통해 코루틴을 중단하거나 결과를 기다릴 수 있다(start(), join(), cancel(), cancelAndJoin(), cancelChildren())

Channels

interface SendChannel<in E> {
    suspend fun send(element: E)
    fun close(): Boolean
}

interface ReceiveChannel<out E> {
    suspend fun receive(): E
}

interface Channel<E> : SendChannel<E>, ReceiveChannel<E>

Usages

fun main() = runBlocking<Unit> {
    val channel = Channel<String>()
    launch {
        channel.send("A1")
        channel.send("A2")
        log("A done")
    }
    launch {
        channel.send("B1")
        log("B done")
    }
    launch {
        repeat(3) {
            val x = channel.receive()
            log(x)
        }
    }
}
suspend fun loadContributorsChannels(
    service: GitHubService,
    req: RequestData,
    updateResults: suspend (List<User>, completed: Boolean) -> Unit
) = coroutineScope {

    val repos = service
        .getOrgRepos(req.org)
        .also { logRepos(req, it) }
        .bodyList()

    val channel = Channel<List<User>>()
    for (repo in repos) {
        launch {
            val users = service.getRepoContributors(req.org, repo.name)
                .also { logUsers(repo, it) }
                .bodyList()
            channel.send(users)
        }
    }
    var allUsers = emptyList<User>()
    repeat(repos.size) {
        val users = channel.receive()
        allUsers = (allUsers + users).aggregate()
        updateResults(allUsers, it == repos.lastIndex)
    }
}

Testing coroutines

runTest: uses virtual time where delay increases