← Назад к вопросам

В чем разница между Launch и Async в Couroutin builder?

2.0 Middle🔥 252 комментариев
#Многопоточность и асинхронность

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между launch и async в Coroutine Builder

В Kotlin Coroutines, launch и async — это два основных билдера для запуска корутин, но они служат разным целям и имеют ключевые различия в поведении и возвращаемых значениях.

Основное назначение

launch используется для запуска корутины, которая выполняет задачу "fire-and-forget" (запустил и забыл). Она не возвращает результат напрямую, а возвращает объект Job, через который можно управлять жизненным циклом корутины (отмена, ожидание завершения). Это аналог выполнения работы в фоновом потоке без ожидания результата.

async предназначена для запуска корутины, которая вычисляет некоторый результат. Она возвращает объект Deferred<T> (который является наследником Job), представляющий "обещание" будущего результата. Для получения самого результата необходимо вызвать await() на объекте Deferred. Это аналог Future или Promise в других языках.

Ключевые различия

  1. Возвращаемое значение

    • launchJob
    • asyncDeferred<T>
  2. Обработка исключений

    • Исключения в launch немедленно приводят к сбою родительской корутины, если не обработаны внутри или с помощью CoroutineExceptionHandler.
    • Исключения в async не выбрасываются сразу, а "оборачиваются" в объект Deferred и выбрасываются только при вызове await().
  3. Предназначение

    • launch — для фоновых задач, где результат не нужен (логирование, обновление UI после вычислений, отправка аналитики).
    • async — для параллельных вычислений с возвратом результата, часто используется для распараллеливания работы.

Примеры использования

launch — фоновое выполнение без результата

scope.launch {
    // Фоновая задача, результат не возвращается
    delay(1000)
    println("Task completed")
}
// Можно управлять через Job: job.cancel(), job.join()

async — параллельные вычисления с результатом

val deferred1 = scope.async { fetchUserData() }
val deferred2 = scope.async { fetchPosts() }

// Параллельное выполнение, затем ожидание обоих результатов
val user = deferred1.await() // Может выбросить исключение из fetchUserData()
val posts = deferred2.await()

Распараллеливание с async

val time = measureTimeMillis {
    val result1 = async { computeSomething(1) }
    val result2 = async { computeSomething(2) }
    val total = result1.await() + result2.await() // Оба вычисления выполнятся параллельно
}

Важные особенности

  • async немедленно стартует корутину при вызове (как и launch), не дожидаясь await().
  • await() — suspending функция, которая приостанавливает корутину до получения результата, но не блокирует поток.
  • Для обработки исключений в async используйте try-catch внутри корутины или вокруг await().
  • launch с Job позволяет организовывать иерархии отмены через родительские-дочерние корутины.

Когда что использовать

Критерийlaunchasync
Нужен результат вычисленийНетДа
Параллельное выполнениеНе напрямуюОсновное применение
Обработка исключенийЧерез CoroutineExceptionHandlerЧерез try-catch при await()
Управление жизненным цикломДа (через Job)Да (через Deferred<Job>)

На практике async часто используется внутри корутины, запущенной через launch, для организации параллельных вычислений, результат которых затем используется для обновления UI или дальнейшей обработки.

В чем разница между Launch и Async в Couroutin builder? | PrepBro