Coroutine Builder: wat is het, soorten coroutine-builders en hoe ze werken

Auteur: IT Sectr Gepubliceerd: 2026-06-21 Leestijd: 8 min

Coroutine Builder — functies van Kotlin Coroutines die coroutines creëren en starten, en de manier van uitvoering bepalen. De builders launch, async, runBlocking en produce dekken verschillende scenario's: van achtergrondtaken tot parallelle berekeningen met terugkeer van resultaat. Volgens JetBrains, 2024 is Coroutine Builder de basis van het coroutine-model en zorgt het voor gestructureerde concurrentie en levenscyclusbeheer.

Belangrijkste punten

  • Coroutine Builder — functie die een coroutine creëert in een specifieke CoroutineScope
  • launch — start een coroutine zonder resultaat terug te geven, retourneert een Job-object
  • async — start een coroutine met terugkeer van Deferred, waardoor het resultaat via await() kan worden verkregen
  • runBlocking — blokkeert de huidige thread, gebruikt als brug tussen blocking- en suspending-code
  • produce — creëert een coroutine met een kanaal voor streamgewijze gegevensoverdracht (verouderd ten gunste van Flow)

Wat is Coroutine Builder?

Coroutine Builder — is een Kotlin-uitbreidingsfunctie die CoroutineScope en een suspend-blok accepteert, en een nieuwe coroutine creëert en start. Elke builder bepaalt hoe de coroutine wordt uitgevoerd: met of zonder resultaat, met blokkering van de thread of asynchroon. Builders zijn ingangspunten tot het coroutine-model van de taal.

Alle builders werken via CoroutineScope, die de levenscyclus van onderliggende coroutines beheert. Bij annulering van de scope worden alle coroutines die erdoor zijn gestart automatisch geannuleerd — dit is het principe van gestructureerde concurrentie. Deze aanpak voorkomt coroutine-lekken en garandeert een voorspelbare voltooiing.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Builders werken binnen CoroutineScope
    val job = launch {
        delay(1000L)
        println("Wereld!")
    }
    println("Hallo,")
    job.join()
}

Belangrijkste soorten coroutine-builders

Kotlin biedt vier ingebouwde coroutine-builders: launch, async, runBlocking en produce. Elk heeft zijn eigen retourtype en toepassingsgebied. Voor mobiele ontwikkeling op Android zijn launch en async de belangrijkste — ze werken niet-blokkerend en integreren met architectuurcomponenten.

BuilderRetourtypeThread-blokkeringScenario
launchJobNeeFire-and-forget taken
asyncDeferred<T>NeeParallelle berekeningen
runBlockingTJaTesten, main-functie
produceReceiveChannel<E>NeeStreamgewijze overdracht (deprecated)

Elke builder accepteert extra parameters: CoroutineStart (startstrategie), CoroutineContext (dispatcher, uitzonderingen) en een benoemd codeblok. Standaard wordt de coroutine onmiddellijk gestart (CoroutineStart.DEFAULT).

launch: fire-and-forget starten

launch — de meest gebruikte builder in Android-ontwikkeling. Het start een coroutine die geen resultaat retourneert en geeft een Job-object terug voor het beheren van de levenscyclus. Dit is de ideale keuze voor operaties waarbij alleen een neveneffect nodig is: opslaan in database, verzenden van analytics, UI-update.

Syntaxis en gebruik van launch

De builder launch accepteert CoroutineScope, optionele CoroutineContext en een suspend-blok. De geretourneerde Job maakt het mogelijk de coroutine te annuleren, op voltooiing te wachten of de status te controleren.

kotlin
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
    val data = fetchFromNetwork()
    saveToDatabase(data)
}
job.start()
job.join()

De parameter CoroutineStart.LAZY stelt het starten uit tot een expliciete aanroep van start() of join(). Dit is handig voor uitgestelde initialisatie en voorwaardelijk starten. Voor standaard onmiddellijk starten wordt CoroutineStart.DEFAULT gebruikt of de parameter weggelaten.

async: parallelle berekeningen met resultaat

async — builder die Deferred<T> retourneert — een asynchrone belofte van resultaat. De aanroep await() onderbreekt de coroutine tot het resultaat is verkregen, zonder de thread te blokkeren. Dit is het belangrijkste mechanisme voor parallelle taken in Kotlin-coroutines.

Twee verzoeken parallel starten

async is bijzonder effectief wanneer meerdere onafhankelijke operaties tegelijk moeten worden uitgevoerd. In tegenstelling tot sequentiële aanroep van suspend-functies, start async coroutines parallel, waardoor de totale uitvoeringstijd wordt verkort.

kotlin
suspend fun fetchUserData(): UserData {
    val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
    val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
    val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
    return UserData(
        profile = deferred1.await(),
        settings = deferred2.await(),
        notifications = deferred3.await()
    )
}

Deferred erft van Job, dus async ondersteunt alle levenscyclusoperaties: annuleren, wachten op voltooiing, afhandeling van uitzonderingen. Bij annulering van de scope worden onderliggende Deferred-coroutines automatisch geannuleerd.

runBlocking: brug naar de blocking-wereld

runBlocking — de enige builder die de huidige thread blokkeert tot voltooiing van de coroutine. Het creëert een nieuwe CoroutineScope en start de doorgegeven coroutine, waarbij de aanroepende thread wordt geblokkeerd. Wordt gebruikt in ingangspunten main(), in testen en bij integratie met blocking-code.

Wanneer is runBlocking nodig

runBlocking is gerechtvaardigd in drie scenario's: het ingangspunt van de applicatie (main), unittesten van suspend-functies en integratie met callback-gebaseerde bibliotheken waar suspend niet kan worden gebruikt. In productiecode van Android wordt het gebruik van runBlocking op de hoofdthread ten zeerste afgeraden.

kotlin
class CoroutineTest {
    @Test
    fun `test suspend function`() = runBlocking {
        val result = mySuspendFunction()
        assertEquals("expected", result)
    }
}

Voor testen wordt aanbevolen kotlinx-coroutines-test met TestCoroutineDispatcher te gebruiken in plaats van runBlocking — dit biedt tijdscontrole en voorkomt blokkades in de testomgeving.

Hoe kies je de juiste builder

De keuze van Coroutine Builder hangt af van het geretourneerde resultaat en het uitvoeringsscenario. Als de operatie geen gegevens retourneert — gebruik launch. Als het resultaat van een asynchrone operatie nodig is — async. runBlocking pas je alleen toe voor bridging, en produce vervang je door Flow voor reactieve streams.

Praktische aanbevelingen voor Android

In Android-projecten met Kotlin Coroutines zijn launch en async het belangrijkste paar builders. launch wordt gebruikt in ViewModel en UseCases voor het starten van coroutines, en async — voor parallelle verzoeken naar het netwerk of database. Moderne bibliotheken (Ktor, Room) ondersteunen al suspend-functies, wat de noodzaak van direct gebruik van async minimaliseert.

  • launch — voor fire-and-forget (loggen, analytics, cachen)
  • async — voor parallelle verzoeken met combineren van resultaten
  • runBlocking — alleen in main() en testen (niet in productie op de Main-thread)
  • produce — vervangen door Flow / SharedFlow / StateFlow

Veelgestelde vragen

Wat is het verschil tussen launch en async in Kotlin?

launch retourneert Job en geeft geen uitvoeringsresultaat terug, terwijl async Deferred<T> retourneert — een object waaruit het resultaat via await() kan worden verkregen. launch wordt gebruikt voor fire-and-forget-operaties, async — voor taken die gegevens retourneren.

Kan runBlocking worden gebruikt in Android Activity?

Wordt afgeraden. runBlocking op de hoofdthread veroorzaakt ANR en blokkeert de UI. Gebruik lifecycleScope.launch binnen Activity en Fragment — dit is een ingebouwde oplossing zonder blokkades.

Wat retourneert de builder launch?

De builder launch retourneert een Job-object waarmee de levenscyclus van de coroutine kan worden beheerd: annuleren (cancel), wachten op voltooiing (join), status controleren (isActive, isCompleted, isCancelled).

Wat is Deferred in Kotlin Coroutines?

Deferred<T> — is een asynchrone belofte van resultaat, geretourneerd door de builder async. Het erft van Job en voegt methoden await() toe voor het verkrijgen van resultaat, getCompleted() voor niet-blokkerende toegang en getCompletionExceptionOrNull() voor controle op uitzonderingen.

Hoe start je launch met vertraging?

Gebruik de parameter CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Roep vervolgens job.start() of job.join() aan voor de daadwerkelijke start. Dit is handig voor uitgestelde initialisatie en voorwaardelijke uitvoering van coroutines.

Samenvatting

  • Coroutine Builder — functie voor het creëren van een coroutine die de uitvoeringswijze en het retourtype bepaalt
  • launch — belangrijkste builder voor taken zonder resultaat, retourneert Job voor beheer van de coroutine
  • async — builder voor parallelle berekeningen, retourneert Deferred met mogelijkheid tot await() van het resultaat
  • runBlocking — blokkerende builder voor main() en testen, niet aanbevolen op de hoofdthread van Android
  • Gestructureerde concurrentie garandeert automatische annulering van onderliggende coroutines bij annulering van de scope
  • produce is verouderd — gebruik Flow, SharedFlow of StateFlow voor reactieve gegevensstromen
  • De keuze van builder hangt af van het scenario: fire-and-forget → launch, parallelle gegevens → async, bridging → runBlocking

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook