Coroutine Builder: шта је то, врсте билдера корутина и како раде

Аутор: IT Sectr Објављено: 2026-06-21 Време читања: 8 мин

Coroutine Builder — функције Kotlin Coroutines које креирају и покрећу корутине, одређујући начин њиховог извршавања. Билдери launch, async, runBlocking и produce покривају различите сценарије: од позадинских задатака до паралелних израчунавања са враћањем резултата. Према подацима JetBrains, 2024, Coroutine Builder је основа модела корутина, обезбеђујући структурирану конкурентност и управљање животним циклусом.

Главно

  • Coroutine Builder — функција која креира корутину у одређеном CoroutineScope-у
  • launch — покреће корутину без враћања резултата, враћа објекат Job
  • async — покреће корутину са враћањем Deferred-а, омогућавајући добијање резултата кроз await()
  • runBlocking — блокира тренутну нит, користи се као мост између blocking и suspending кода
  • produce — креира корутину са каналом за стримовни пренос података (застарело у корист Flow-а)

Шта је Coroutine Builder?

Coroutine Builder — је функција проширења Kotlin-а која прима CoroutineScope и suspend-блок, креирајући и покрећући нову корутину. Сваки билдер одређује како ће корутина бити извршена: са или без враћања резултата, са блокирањем нити или асинхроно. Билдери су улазне тачке у модел корутина језика.

Сви билдери раде кроз CoroutineScope, који управља животним циклусом подређених корутина. При отказивању scope-а, све корутине покренуте кроз њега се аутоматски отказују — ово је принцип структуриране конкурентности. Овај приступ спречава цурење корутина и гарантује предвидљиво завршавање.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Билдери раде унутар CoroutineScope-а
    val job = launch {
        delay(1000L)
        println("Свете!")
    }
    println("Здраво,")
    job.join()
}

Главне врсте билдера корутина

Kotlin пружа четири уграђена билдера корутина: launch, async, runBlocking и produce. Сваки од њих има свој повратни тип и област примене. За мобилни развој на Android-у, главни су launch и async — они раде неблокирајуће и интегришу се са архитектонским компонентама.

БилдерПовратни типБлокирање нитиСценарио
launchJobНеFire-and-forget задаци
asyncDeferred<T>НеПаралелна израчунавања
runBlockingTДаТестови, main функција
produceReceiveChannel<E>НеСтримовни пренос (deprecated)

Сваки билдер прима додатне параметре: CoroutineStart (стратегија покретања), CoroutineContext (диспечер, изузеци) и именовани блок кода. Подразумевано, корутина се покреће одмах (CoroutineStart.DEFAULT).

launch: fire-and-forget покретање

launch — најчешће коришћени билдер у Android развоју. Покреће корутину која не враћа резултат и враћа објекат Job за управљање њеним животним циклусом. Ово је идеалан избор за операције где је потребан само споредни ефекат: чување у бази, слање аналитике, ажурирање UI-ја.

Синтакса и употреба launch-а

Билдер launch прима CoroutineScope, опциони CoroutineContext и suspend-блок. Повратни Job омогућава отказивање корутине, чекање на њено завршавање или проверу статуса.

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

Параметар CoroutineStart.LAZY одлаже покретање до експлицитног позива start() или join(). Ово је корисно за одложену иницијализацију и условно покретање. За стандардно тренутно покретање користи се CoroutineStart.DEFAULT или се параметар изоставља.

async: паралелна израчунавања са резултатом

async — билдер који враћа Deferred<T> — асинхроно обећање резултата. Позив await() суспендује корутину до добијања резултата, не блокирајући нит. Ово је основни механизам за паралелне задатке у корутинама Kotlin-а.

Паралелно покретање два захтева

async је посебно ефикасан када је потребно извршити више независних операција истовремено. За разлику од секвенцијалног позивања suspend-функција, async покреће корутине паралелно, смањујући укупно време извршавања.

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 наслеђује Job, тако да async подржава све операције животног циклуса: отказивање, чекање на завршетак, обраду изузетака. При отказивању scope-а, подређене Deferred корутине се отказују аутоматски.

runBlocking: мост у blocking свет

runBlocking — једини билдер који блокира тренутну нит до завршетка корутине. Креира нови CoroutineScope и покреће прослеђену корутину, блокирајући позивајућу нит. Користи се у улазним тачкама main(), у тестовима и при интеграцији са blocking кодом.

Када је runBlocking неопходан

runBlocking је оправдан у три сценарија: улазна тачка апликације (main), јединични тестови suspend-функција и интеграција са callback-based библиотекама где се suspend не може користити. У production коду Android-а, коришћење runBlocking-а на главној нити категорички се не препоручује.

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

За тестове се препоручује коришћење kotlinx-coroutines-test са TestCoroutineDispatcher уместо runBlocking-а — ово обезбеђује контролу времена и избегава блокирање у тестном окружењу.

Како одабрати одговарајући билдер

Избор Coroutine Builder-а зависи од повратног резултата и сценарија извршавања. Ако операција не захтева враћање података — користите launch. Ако је потребан резултат асинхроне операције — async. runBlocking примењујте само за bridging, а produce замените Flow-ом за реактивне токове.

Практичне препоруке за Android

У Android пројектима са Kotlin Coroutines, главни пар билдера су launch и async. launch се користи у ViewModel и UseCases за покретање корутина, а async — за паралелне захтеве ка мрежи или бази. Модерне библиотеке (Ktor, Room) већ подржавају suspend-функције, што минимизује потребу за директним коришћењем async-а.

  • launch — за fire-and-forget (логирање, аналитика, кеширање)
  • async — за паралелне захтеве са обједињавањем резултата
  • runBlocking — само у main() и тестовима (не у production на Main-нити)
  • produce — заменити са Flow / SharedFlow / StateFlow

Често постављана питања

Чему се разликује launch од async у Kotlin-у?

launch враћа Job и не враћа резултат извршавања, а async враћа Deferred<T> — објекат из којег се може добити резултат кроз await(). launch се користи за fire-and-forget операције, async — за задатке који враћају податке.

Може ли се користити runBlocking у Android Activity?

Не препоручује се. runBlocking на главној нити изазива ANR и блокира UI. Користите lifecycleScope.launch унутар Activity и Fragment — ово је уграђено решење без блокирања.

Шта враћа билдер launch?

Билдер launch враћа објекат Job који омогућава контролу животног циклуса корутине: отказивање (cancel), чекање на завршетак (join), проверу статуса (isActive, isCompleted, isCancelled).

Шта је Deferred у Kotlin Coroutines?

Deferred<T> — је асинхроно обећање резултата које враћа билдер async. Наслеђује Job и додаје методе await() за добијање резултата, getCompleted() за неблокирајући приступ и getCompletionExceptionOrNull() за проверу изузетка.

Како покренути launch са кашњењем?

Користите параметар CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Затим позовите job.start() или job.join() за стварно покретање. Ово је корисно за одложену иницијализацију и условно извршавање корутина.

Закључак

  • Coroutine Builder — функција креирања корутине која одређује начин њеног извршавања и повратни тип
  • launch — главни билдер за задатке без враћања резултата, враћа Job за управљање корутином
  • async — билдер за паралелна израчунавања, враћа Deferred са могућношћу await() резултата
  • runBlocking — блокирајући билдер за main() и тестове, не препоручује се на главној нити Android-а
  • Структурирана конкурентност гарантује аутоматско отказивање подређених корутина при отказивању scope-а
  • produce је застарео — користите Flow, SharedFlow или StateFlow за реактивне токове података
  • Избор билдера зависи од сценарија: fire-and-forget → launch, паралелни подаци → async, bridging → runBlocking

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође