Поиск с debounce на Flow
Вопрос
Опиши, как на Flow сделать поиск по мере ввода: какие операторы и почему.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Источник: MutableStateFlow с текстом запроса
debounce, чтобы не слать запрос на каждую букву
filter по длине и distinctUntilChanged
flatMapLatest отменяет устаревший запрос
catch для ошибок, flowOn или main-safe репозиторий
stateIn в ViewModel с WhileSubscribed
Что могут спросить следом
- Что будет, если заменить flatMapLatest на flatMapMerge?
- Как показать индикатор загрузки?
- Как протестировать debounce?
Разбор
Текст поля храню в MutableStateFlow<String> во ViewModel. Дальше цепочка: debounce(300), чтобы не дёргать сеть на каждую букву; filter по минимальной длине; distinctUntilChanged, чтобы не повторять тот же запрос. Главный оператор flatMapLatest: на каждый новый запрос он запускает поиск и отменяет предыдущий, поэтому медленный ответ на старый запрос не перетрёт свежий. Если взять flatMapMerge, ответы придут в произвольном порядке, и на экране может оказаться результат устаревшего запроса. Ошибки ловлю внутри flatMapLatest через catch, чтобы падение одного запроса не убило весь поток. Репозиторий main-safe, тяжёлую обработку выношу в flowOn(Dispatchers.Default). В конце stateIn(viewModelScope, WhileSubscribed(5000), начальное) и в Compose collectAsStateWithLifecycle. Тестирую через runTest и виртуальное время, advanceTimeBy проверяет debounce без реального ожидания.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.