Coroutine Builder: ce este, tipuri de constructori de corutine și cum funcționează

Autor: IT Sectr Publicat: 2026-06-21 Timp de citire: 8 min

Coroutine Builder — funcții Kotlin Coroutines care creează și lansează corutine, determinând modul lor de execuție. Constructorii launch, async, runBlocking și produce acoperă diferite scenarii: de la sarcini de fundal la calcule paralele cu returnarea rezultatului. Conform JetBrains, 2024, Coroutine Builder este baza modelului de corutine, asigurând concurență structurată și gestionarea ciclului de viață.

Principalele

  • Coroutine Builder — funcție care creează o corutină într-un CoroutineScope specific
  • launch — lansează o corutină fără returnarea rezultatului, returnează un obiect Job
  • async — lansează o corutină cu returnarea Deferred, permițând obținerea rezultatului prin await()
  • runBlocking — blochează firul curent, folosit ca punte între codul blocking și suspending
  • produce — creează o corutină cu un canal pentru transmiterea în flux a datelor (învechit în favoarea Flow)

Ce este Coroutine Builder?

Coroutine Builder — este o funcție de extensie Kotlin care primește CoroutineScope și un suspend-bloc, creând și lansând o nouă corutină. Fiecare constructor determină modul în care corutina va fi executată: cu sau fără returnarea rezultatului, cu blocarea firului sau asincron. Constructorii sunt puncte de intrare în modelul de corutine al limbajului.

Toți constructorii funcționează prin CoroutineScope, care gestionează ciclul de viață al corutinelor copil. La anularea scope-ului, toate corutinele lansate prin el sunt anulate automat — acesta este principiul concurenței structurate. Această abordare previne scurgerile de corutine și garantează o finalizare previzibilă.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Constructorii rulează în interiorul CoroutineScope
    val job = launch {
        delay(1000L)
        println("Lume!")
    }
    println("Salut,")
    job.join()
}

Tipurile principale de constructori de corutine

Kotlin oferă patru constructori încorporați de corutine: launch, async, runBlocking și produce. Fiecare are propriul tip returnat și domeniul de aplicare. Pentru dezvoltarea mobilă pe Android, principalii sunt launch și async — funcționează neblocant și se integrează cu componentele arhitecturale.

ConstructorTip returnatBlocare firScenariu
launchJobNuSarcini fire-and-forget
asyncDeferred<T>NuCalcule paralele
runBlockingTDaTeste, funcția main
produceReceiveChannel<E>NuTransmitere în flux (deprecated)

Fiecare constructor acceptă parametri suplimentari: CoroutineStart (strategia de lansare), CoroutineContext (dispecer, excepții) și un bloc de cod denumit. Implicit, corutina este lansată imediat (CoroutineStart.DEFAULT).

launch: lansare fire-and-forget

launch — cel mai utilizat constructor în dezvoltarea Android. Lansează o corutină care nu returnează rezultat și returnează un obiect Job pentru gestionarea ciclului său de viață. Este alegerea ideală pentru operații unde este necesar doar un efect secundar: salvare în BD, trimitere analitică, actualizare UI.

Sintaxa și utilizarea lui launch

Constructorul launch primește CoroutineScope, un CoroutineContext opțional și un suspend-bloc. Job returnat permite anularea corutinei, așteptarea finalizării sau verificarea stării.

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

Parametrul CoroutineStart.LAZY amână lansarea până la apelarea explicită a start() sau join(). Acest lucru este util pentru inițializarea întârziată și lansarea condiționată. Pentru lansarea imediată standard se utilizează CoroutineStart.DEFAULT sau parametrul este omis.

async: calcule paralele cu rezultat

async — constructor care returnează Deferred<T> — o promisiune asincronă a rezultatului. Apelul await() suspendă corutina până la obținerea rezultatului, fără a bloca firul. Acesta este mecanismul principal pentru sarcini paralele în corutinele Kotlin.

Lansarea a două cereri în paralel

async este deosebit de eficient când trebuie executate mai multe operații independente simultan. Spre deosebire de apelarea secvențială a funcțiilor suspend, async lansează corutinele în paralel, reducând timpul total de execuție.

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 moștenește din Job, deci async suportă toate operațiile ciclului de viață: anulare, așteptare finalizare, gestionare excepții. La anularea scope-ului, corutinele copil Deferred sunt anulate automat.

runBlocking: puntea către lumea blocking

runBlocking — singurul constructor care blochează firul curent până la finalizarea corutinei. Creează un nou CoroutineScope și lansează corutina transmisă, blocând firul apelant. Este utilizat în punctele de intrare main(), în teste și la integrarea cu cod blocking.

Când este necesar runBlocking

runBlocking este justificat în trei scenarii: punctul de intrare al aplicației (main), testele unitare ale funcțiilor suspend și integrarea cu biblioteci bazate pe callback-uri unde nu se poate folosi suspend. În codul de producție Android, utilizarea runBlocking pe firul principal nu este categoric recomandată.

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

Pentru teste se recomandă utilizarea kotlinx-coroutines-test cu TestCoroutineDispatcher în loc de runBlocking — aceasta asigură controlul timpului și evită blocările în mediul de testare.

Cum să alegi constructorul potrivit

Alegerea Coroutine Builder depinde de rezultatul returnat și de scenariul de execuție. Dacă operația nu necesită returnarea datelor — utilizați launch. Dacă este necesar rezultatul unei operații asincrone — async. runBlocking aplicați doar pentru bridging, iar produce înlocuiți-l cu Flow pentru fluxuri reactive.

Recomandări practice pentru Android

În proiectele Android cu Kotlin Coroutines, perechea principală de constructori este launch și async. launch este utilizat în ViewModel și UseCases pentru lansarea corutinelor, iar async — pentru cereri paralele la rețea sau bază de date. Bibliotecile moderne (Ktor, Room) suportă deja funcții suspend, ceea ce minimizează necesitatea utilizării directe a lui async.

  • launch — pentru fire-and-forget (logare, analitică, cache)
  • async — pentru cereri paralele cu combinarea rezultatelor
  • runBlocking — doar în main() și teste (nu în producție pe Main-thread)
  • produce — înlocuiți cu Flow / SharedFlow / StateFlow

Întrebări frecvente

Cu ce diferă launch de async în Kotlin?

launch returnează Job și nu returnează rezultatul execuției, iar async returnează Deferred<T> — un obiect din care se poate obține rezultatul prin await(). launch este utilizat pentru operații fire-and-forget, async — pentru sarcini care returnează date.

Se poate folosi runBlocking în Android Activity?

Nu este recomandat. runBlocking pe firul principal cauzează ANR și blochează UI. Utilizați lifecycleScope.launch în interiorul Activity și Fragment — aceasta este o soluție încorporată fără blocări.

Ce returnează constructorul launch?

Constructorul launch returnează un obiect Job care permite controlarea ciclului de viață al corutinei: anulare (cancel), așteptare finalizare (join), verificare stare (isActive, isCompleted, isCancelled).

Ce este Deferred în Kotlin Coroutines?

Deferred<T> — este o promisiune asincronă a rezultatului, returnată de constructorul async. Moștenește din Job și adaugă metodele await() pentru obținerea rezultatului, getCompleted() pentru acces neblocant și getCompletionExceptionOrNull() pentru verificarea excepției.

Cum să lansezi launch cu întârziere?

Utilizați parametrul CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Apoi apelați job.start() sau job.join() pentru lansarea efectivă. Acest lucru este util pentru inițializarea întârziată și executarea condiționată a corutinelor.

Rezumat

  • Coroutine Builder — funcție de creare a corutinei care determină modul de execuție și tipul returnat
  • launch — constructor principal pentru sarcini fără returnarea rezultatului, returnează Job pentru gestionarea corutinei
  • async — constructor pentru calcule paralele, returnează Deferred cu posibilitatea await() a rezultatului
  • runBlocking — constructor blocant pentru main() și teste, nerecomandat pe firul principal Android
  • Concurența structurată garantează anularea automată a corutinelor copil la anularea scope-ului
  • produce este învechit — utilizați Flow, SharedFlow sau StateFlow pentru fluxuri reactive de date
  • Alegerea constructorului depinde de scenariu: fire-and-forget → launch, date paralele → async, bridging → runBlocking

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și