Давайте разберём всё по шагам. Что происходит, если отменить корутину, где происходит collect()?
val job = scope.launch {
flow.collect { value ->
println("Value: $value")
}
}
job.cancel()
При отмене:
- Отменяется
CoroutineScope/Job - Отмена прокидывается в
collect {} - Внутри
flow {}вызываетсяCancellationException - Выполнение останавливается немедленно (если ты не подавил исключение)
- Ресурсы освобождаются (если
finally {}/onCompletion {})
Как Flow узнаёт, что нужно остановиться?
Алгоритм проверки:
collect {}проверяетcoroutineContext.isActiveemit()тоже делает такую проверку- если отменено → выбрасывается
CancellationException
Важно: flow {} должен быть cancellation-cooperative
Сancellation-cooperative — означает, что внутри корутины не должно быть блокирующих элементов.
Действие внутри flow | Реакция на отмену корутины |
|---|---|
delay(), emit(), collect() | Хорошо: прерываются автоматически. Они Сancellation-cooperative |
Thread.sleep() | Плохо: не прервётся, блокирует поток |
while(true) {} | Плохо: зациклит, без выхода |