Как отменяется Flow? Что происходит при отмене корутины, в которой идёт collect?

Давайте разберём всё по шагам. Что происходит, если отменить корутину, где происходит collect()?

val job = scope.launch {
    flow.collect { value ->
        println("Value: $value")
    }
}
job.cancel()

При отмене:

  1. Отменяется CoroutineScope / Job
  2. Отмена прокидывается в collect {}
  3. Внутри flow {} вызывается CancellationException
  4. Выполнение останавливается немедленно (если ты не подавил исключение)
  5. Ресурсы освобождаются (если finally {} / onCompletion {})

Как Flow узнаёт, что нужно остановиться?

Алгоритм проверки:

  • collect {} проверяет coroutineContext.isActive
  • emit() тоже делает такую проверку
  • если отменено → выбрасывается CancellationException

Важно: flow {} должен быть cancellation-cooperative

Сancellation-cooperative — означает, что внутри корутины не должно быть блокирующих элементов.

Действие внутри flowРеакция на отмену корутины
delay(), emit(), collect()Хорошо: прерываются автоматически. Они Сancellation-cooperative
Thread.sleep()Плохо: не прервётся, блокирует поток
while(true) {}Плохо: зациклит, без выхода


Опубликовано

в

,

от

Метки: