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

Что такое scope у корутин?

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

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

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

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

Что такое Scope в корутинах?

Scope (область видимости или жизненный цикл) в корутинах — это фундаментальное понятие, определяющее время жизни корутины и управление её отменой. Можно сказать, что это "контекст выполнения", который устанавливает границы, внутри которых корутина может работать. Каждая корутина всегда запускается в рамках какого-либо CoroutineScope.

Основные аспекты CoroutineScope

  1. Управление жизненным циклом Scope отвечает за автоматическую отмену всех дочерних корутин при его отмене. Это предотвращает утечки памяти и ненужную работу.

  2. Структурированный параллелизм Ключевой принцип, при котором дочерние корутины наследуют контекст родителя (включая Job) и завершаются вместе с ним.

  3. Контекст выполнения Scope содержит CoroutineContext, включающий:

    • Dispatcher (поток выполнения)
    • Job (задача, управляющая жизненным циклом)
    • CoroutineExceptionHandler (обработчик исключений)

Типы Scope в Kotlin Coroutines

1. GlobalScope

Область видимости на всё время жизни приложения. Использовать нужно с осторожностью, так как корутины в этом scope не отменяются автоматически.

// Пример (не рекомендуется для большинства случаев)
GlobalScope.launch {
    // Эта корутина будет жить, пока не завершится или пока не завершится всё приложение
    delay(1000)
    println("Выполнено в GlobalScope")
}

2. LifecycleScope (androidx.lifecycle)

Связан с жизненным циклом компонентов Android (Activity, Fragment, ViewModel).

// В Activity или Fragment
lifecycleScope.launch {
    // Корутина будет автоматически отменена при разрушении компонента
    fetchData()
}

class MyViewModel : ViewModel() {
    fun loadData() {
        viewModelScope.launch {
            // Автоматическая отмена при очистке ViewModel
            repository.loadItems()
        }
    }
}

3. ViewModelScope

Специальный scope для ViewModel в Android Architecture Components.

4. Пользовательские Scope

Можно создавать свои scope для конкретных задач:

// Создание пользовательского scope
val customScope = CoroutineScope(Dispatchers.IO + SupervisorJob())

customScope.launch {
    // Корневые корутины в этом scope
}

// При завершении работы компонента
fun cleanup() {
    customScope.cancel() // Отменяет все корутины в scope
}

Практическое применение и важные паттерны

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

class UserRepository(private val externalScope: CoroutineScope) {
    // Scope как зависимость для тестирования
    
    suspend fun fetchUsers(): List<User> {
        // Использование внешнего scope
        return externalScope.async {
            apiService.getUsers()
        }.await()
    }
}

// В ViewModel
class UserViewModel : ViewModel() {
    private val repositoryScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    
    fun loadUsers() {
        viewModelScope.launch {
            val users = repositoryScope.async {
                repository.fetchUsers()
            }.await()
            // Обработка результата
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        repositoryScope.cancel() // Важно: очистка ресурсов
    }
}

SupervisorJob для независимых операций

val uiScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

uiScope.launch {
    // Эта корутина не отменит другие при ошибке
    throw RuntimeException("Ошибка!")
}

uiScope.launch {
    // Эта корутина продолжит работу, даже если предыдущая упала
    delay(1000)
    updateUI()
}

Ключевые правила использования Scope

  1. Всегда знайте, в каком scope запускаете корутину
  2. Используйте соответствующий жизненному циклу scope в Android
  3. Не используйте GlobalScope без крайней необходимости
  4. Отменяйте кастомные scope при завершении работы компонента
  5. Тестируйте отмену корутин через отмену scope

Обработка исключений в Scope

val handler = CoroutineExceptionHandler { _, exception ->
    println("Поймано исключение: $exception")
}

val scope = CoroutineScope(Dispatchers.Default + SupervisorJob() + handler)

scope.launch {
    // При ошибке здесь будет вызван handler
    throw IllegalStateException("Тестовая ошибка")
}

Итог: Scope в корутинах — это механизм управления жизненным циклом и ресурсами, обеспечивающий безопасную работу с асинхронными операциями. Правильное использование scope позволяет создавать устойчивые, поддерживаемые приложения без утечек памяти и с корректной обработкой отмены операций. В Android контексте привязка scope к жизненному циклу компонентов через lifecycleScope и viewModelScope является обязательной best practice.

Что такое scope у корутин? | PrepBro