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

Какие знаешь способы запуска корутины?

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

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Способы запуска корутин в Kotlin

Основные способы

В Kotlin существует несколько способов запуска корутин, каждый с определённым назначением и характеристиками.

1. launch — для действий без результата

GlobalScope.launch {
    // Код выполняется асинхронно
    delay(1000)
    println("Done")
}

Характеристики:

  • Запускает корутину и не ждёт её завершения
  • Возвращает Job (позволяет отменить корутину)
  • Не возвращает результат
  • Исключения теряются, если не обработаны

Лучшее использование: UI обновления, отправка событий

2. async — для действий с результатом

val result: Deferred<String> = GlobalScope.async {
    delay(1000)
    "Result"
}

// Получить результат
val value = result.await()

Характеристики:

  • Возвращает Deferred с результатом
  • Нужно вызвать await() для получения результата
  • Подходит для параллельных операций
  • Исключения оборачиваются в результат

Лучшее использование: сетевые запросы, вычисления с результатом

3. runBlocking — для блокирования потока

fun main() = runBlocking {
    val result = fetchData()
    println(result)
}

suspend fun fetchData(): String {
    delay(1000)
    return "Data"
}

Характеристики:

  • Блокирует текущий поток до завершения корутины
  • Возвращает результат корутины
  • Используется в main() и тестах
  • НЕ ИСПОЛЬЗОВАТЬ на UI потоке

Лучшее использование: точка входа в корутины, тесты

4. CoroutineScope — правильный способ

class MyViewModel : ViewModel() {
    fun loadData() {
        viewModelScope.launch {
            try {
                val data = withContext(Dispatchers.IO) {
                    fetchFromNetwork()
                }
                // Обновить UI (автоматически на Main потоке)
                updateUI(data)
            } catch (e: Exception) {
                handleError(e)
            }
        }
    }
}

Встроенные Scope:

  • viewModelScope — привязан к жизненному циклу ViewModel
  • lifecycleScope — привязан к Activity/Fragment
  • rememberCoroutineScope — в Compose

5. withContext — переключение контекста

suspend fun loadUserData(): User = withContext(Dispatchers.IO) {
    // Выполняется в IO потоке
    database.getUser()
    // Автоматически возвращает результат в вызывающий контекст
}

Характеристики:

  • Переключает dispatcher внутри корутины
  • Возвращает результат функции
  • Идеален для suspend функций

Сравнение способов

СпособРезультатЖдётИспользование
launch❌ JobДействия без результата
async✅ Deferred✅ (await)Параллельные операции
runBlocking✅ Tmain(), тесты
withContext✅ TВ suspend функциях

Важные замечания

  • GlobalScope.launch — НИКОГДА не используйте в production (утечки памяти)
  • viewModelScope — всегда используйте в ViewModel (автоматическая отмена)
  • Exception handling — обработка исключений отличается в launch и async
  • Dispatcher выбор — Main для UI, IO для сети/БД, Default для вычислений