async: vad är det, Deferred och parallella korutiner hur de fungerar

Författare: IT Sectr Publicerad: 2026-06-22 Lästid: 8 min

async — Coroutine Builder i Kotlin som startar en korutin och returnerar ett Deferred<T>-objekt för att få resultatet av en asynkron operation. async gör det möjligt att utföra flera uppgifter parallellt och aggregera deras resultat via await(). Enligt JetBrains guide, 2024 är async det föredragna sättet att organisera parallella beräkningar i korutiner.

Huvudpunkter

  • async — korutinbyggare som returnerar Deferred<T> med resultatet av en asynkron operation
  • Deferred — asynkront löfte, som ärver Job, med metoden await() för att få resultatet
  • async möjliggör parallell exekvering av oberoende uppgifter, vilket minskar den totala tiden
  • await() — suspend-funktion som pausar korutinen tills resultatet erhålls utan blockering
  • Strukturerad samtidighet med async garanterar avbrott av alla parallella uppgifter vid fel

Vad är async i Kotlin Coroutines?

async — är en utökningsfunktion för CoroutineScope som skapar en korutin med resultatåtergivning. Till skillnad från launch returnerar async Deferred<T> — ett objekt som representerar ett framtida värde. Korutinen som startas via async exekveras samtidigt med andra korutiner, vilket möjliggör parallellisering av beräkningar.

async används när resultatet av en asynkron operation behövs för vidare bearbetning: laddning av data från flera källor, batchbearbetning av samlingar, parallella förfrågningar till olika API:er. Deferred skapas omedelbart och resultatet blir tillgängligt efter att korutinen slutförts.

kotlin
import kotlinx.coroutines.*

suspend fun String.delayedValue(): String {
    delay(1000L)
    return this
}

fun main() = runBlocking {
    val deferred: Deferred<String> = async { "Hello".delayedValue() }
    println(deferred.await())
}

Syntax för async och Deferred

Signaturen för async liknar launch: samma parametrar CoroutineContext, CoroutineStart och suspend-block. Skillnaden ligger i returtypen — Deferred<T> istället för Job, där T är typen av resultatet som returneras av blockets sista uttryck.

kotlin
public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
): Deferred<T>

Deferred<T> — gränssnitt som ärver Job och lägger till metoderna await(), getCompleted(), getCompletionExceptionOrNull(). await() är en suspend-funktion och kan endast anropas inuti en korutin eller en annan suspend-funktion. getCompleted() — en icke-blockerande metod som kastar ett undantag om korutinen inte har slutförts ännu.

Parallella uppgifter med async

Den främsta fördelen med async är möjligheten att starta uppgifter parallellt. Istället för sekventiell väntan på varje operation (total tid = summan av tider) startar async korutiner samtidigt, vilket minskar den totala tiden till tiden för den längsta operationen.

Parallell dataladdning

Ett typiskt scenario — laddning av användarprofil, inställningar och orderhistorik med tre parallella async-förfrågningar. Efter att alla tre slutförts kombineras resultaten till en enda datamodell.

kotlin
suspend fun loadUserDashboard(userId: String): Dashboard = coroutineScope {
    val profile = async { api.getProfile(userId) }
    val settings = async { api.getSettings(userId) }
    val orders = async { api.getRecentOrders(userId) }

    Dashboard(
        profile = profile.await(),
        settings = settings.await(),
        orders = orders.await()
    )
}

Funktionen coroutineScope startar underordnade korutiner och väntar på deras slutförande innan resultatet returneras. Hela blocket exekveras parallellt, inte sekventiellt.

Bearbetning av Deferred-resultat

Deferred stöder flera metoder för att arbeta med resultatet. Förutom await() finns metoder för statuskontroll, hämtning av färdigt värde och aggregering av flera Deferred via verktygsfunktioner i Kotlin Coroutines.

MetodBeskrivningSuspend?
await()Pausar korutinen tills resultatet erhållsJa
getCompleted()Returnerar resultatet om korutinen har slutförts (annars Exception)Nej
getCompletionExceptionOrNull()Returnerar undantaget vid fel eller nullNej
isCompletedKontrollerar om korutinen har slutförtsNej

För aggregering av en lista med Deferred används awaitAll() — en funktion som pausar exekveringen tills alla Deferred i samlingen har slutförts. Om minst en har slutförts med fel kastar awaitAll() ett undantag.

kotlin
suspend fun <T> loadAll(requests: List<suspend () -> T>): List<T> {
    return coroutineScope {
        val deferreds = requests.map { async { it() } }
        deferreds.awaitAll()
    }
}

Skillnader mellan async och launch

Valet mellan async och launch beror på om resultatet av korutinens exekvering behövs. launch returnerar Job och är lämplig för fire-and-forget-operationer, async returnerar Deferred och används för uppgifter som returnerar data. När det gäller syntax och parametrar är byggarna identiska.

  • launch → Job (inget resultat), async → Deferred<T> (har resultat T)
  • launch — fire-and-forget-uppgifter (loggning, cachelagring, skicka analys)
  • async — parallella beräkningar (laddning från flera API:er, batchbearbetning)
  • Båda stöder strukturerad samtidighet och CoroutineStart-parametrar
  • await() är endast tillgänglig för Deferred, launch ger inget resultat

Viktig regel: använd aldrig async för fire-and-forget. Om resultatet av korutinen inte behövs, använd launch. async skapar overhead för att skapa Deferred, vilket inte är motiverat i ett sådant scenario.

Exempel på async i mobil utveckling

I Android används async för parallella operationer i ViewModel och UseCases. Typiska scenarier: samtidig laddning av profil och nyhetsflöde, hämtning av väder från flera väder tjänster, batchesynkronisering av data med servern.

kotlin
class HomeViewModel : ViewModel() {
    fun loadHomeScreen() {
        viewModelScope.launch {
            val userData = async(Dispatchers.IO) { repository.getUserData() }
            val newsFeed = async(Dispatchers.IO) { repository.getNewsFeed() }
            val notifications = async(Dispatchers.IO) { repository.getNotifications() }

            val state = HomeState(
                user = userData.await(),
                news = newsFeed.await(),
                unread = notifications.await()
            )
            _uiState.update { state }
        }
    }
}

Det rekommenderas att slå in async-gruppen i coroutineScope eller supervisorScope för feltisolering. supervisorScope gör det möjligt att fortsätta exekveringen av de återstående async-korutinerna även om ett fel uppstår i en av dem — användbart för icke-kritiska operationer.

Vanliga frågor

Kan async användas utan await?

Det kan man, men det är meningslöst. async utan await() startar korutinen, men dess resultat går förlorat. Om resultatet inte behövs, använd launch — det skapar inget Deferred och är mer effektivt när det gäller minne och prestanda.

Hur hanterar async undantag?

Undantaget inuti async lagras i Deferred. Anropet await() vidarebefordrar detta undantag. För kontroll utan vidarebefordran, använd getCompletionExceptionOrNull(). Vid användning av coroutineScope avbryter felet alla underordnade korutiner.

Vad är awaitAll i Kotlin Coroutines?

awaitAll() — en utökningsfunktion för Iterable<Deferred<T>> som pausar korutinen tills alla Deferred har slutförts. Returnerar en lista med resultat. Om minst en Deferred slutförs med fel vidarebefordrar den undantaget och avbryter resten.

Skiljer sig async från GlobalScope.async?

Ja. async är en utökningsfunktion för CoroutineScope, bunden till scopet. GlobalScope.async skapar en korutin utan bindning till livscykeln — den kan köras oändligt. I Android rekommenderas inte GlobalScope på grund av risk för minnesläckor.

Hur många async-korutiner kan startas för parallella förfrågningar?

Antalet bestäms av dispatchern: Dispatchers.IO stöder upp till 64 samtidiga trådar, Dispatchers.Default — baserat på antalet CPU-kärnor. För massiva operationer, använd begränsad parallellitet via Semaphore eller mapNotNull med awaitAll.

Sammanfattning

  • async — korutinbyggare som returnerar Deferred<T> för asynkron resultathämtning
  • Deferred ärver Job och lägger till metoderna await(), getCompleted(), getCompletionExceptionOrNull()
  • Parallell exekvering med async minskar den totala tiden till längden av den längsta operationen
  • awaitAll() — verktyg för att vänta på alla Deferred i en samling
  • coroutineScope — rekommenderad wrapper för en async-grupp med garanti för avbrott
  • Använd inte async för fire-and-forget — tillämpa launch
  • I Android används async för parallell laddning i ViewModel med viewModelScope

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också