CoroutineScope — это контекст выполнения корутин, объединяющая их в одну иерархию. То есть сущность, в которой происходит Структурированная асинхронность. Для легкости понимания её можно сравнить с Android Activity: наши асинхронные вызовы будут выполнятся в рамках CoroutineScope, так же как наши вьюшки(Textview, Button, LieneаrLayout  и др.) существуют в рамках одной Activity. Если CoroutineScope отменяется(закрывается), то все дочерние корутины, так же отменятся, как если бы закрыв Activity наши вьюшки так же уничтожаются.
Виды CoroutineScope
1. CoroutineScope — кастомный(базовый) скоуп, дающий полный контроль. Нужно самому отменять scope.cancel() при завершении.
2. GlobalScope — подходит только для одиночных фоновых задач, например логирования. Но использование его крайне не рекомендуется, так как он не привязан к жизненному циклу и из-за этого может вызывать утечки памяти.
3. viewModelScope — поставляется в androidx.lifecycle. Используется для запуска корутин из ViewModel и Автоматически отменяется при ViewModel.onCleared()
4. lifecycleScope — полезен для UI-задач, короткоживущих задач в рамках жизненного цикла вьюшки. Привязан к жизненному циклу LifecycleOwner и автоматически отменяется в onDestroy()
5. supervisorScope — используется, чтобы исключение в одной дочерней корутине не приводило к отмене других дочерних корутин данного скоупа.