Выбор ответа Senior Flow, StateFlow и SharedFlow обновлено

withContext внутри flow { }

Вопрос

Что будет при сборе такого потока?

val f = flow {
    withContext(Dispatchers.IO) {
        emit(loadFromDisk())
    }
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: IllegalStateException: нарушен инвариант контекста Flow. Flow гарантирует сохранение контекста: emit должен вызываться в контексте коллектора.

Варианты ответа

  1. Всё работает, значения эмитятся из потока IO
  2. Ошибка компиляции: emit недоступен внутри withContext
  3. Значения потеряются без ошибок и без исключений
  4. IllegalStateException: нарушен инвариант контекста Flowправильный ответ

Разбор

Flow гарантирует сохранение контекста: emit должен вызываться в контексте коллектора. Вызов из withContext нарушает это, и при сборе бросится IllegalStateException с текстом про Flow invariant. Компилируется код нормально. Правильный способ сменить поток для upstream это flowOn(Dispatchers.IO), а для эмита из разных корутин есть channelFlow.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.