Flow & Operators Flashcards

KOTLIN › Concurrency

What does it mean that a Flow is cold?
The producer block does not run until a terminal operator collects it, and it runs again independently for every collector. Nothing is shared until you convert it with shareIn/stateIn.
What is the difference between an intermediate and a terminal operator?
Intermediate operators (map, filter, transform, onEach, flowOn) return a new Flow lazily and don't start collection. Terminal operators (collect, toList, first, single) are suspend functions that actually trigger the upstream to run.
What does flowOn change, and what does it leave alone?
flowOn changes the CoroutineContext (e.g. dispatcher) of the upstream flow only, everything declared before it. It is context-preserving: the downstream operators and the collector keep running in the collector's own context.
Why can't you call emit() inside withContext() in a flow {} builder?
Flow enforces context preservation/exception transparency. Emitting from a different context throws IllegalStateException at runtime. To switch the producer's context use flowOn; to emit from another coroutine/callback use channelFlow or callbackFlow.
What does the catch operator catch, and what does it NOT catch?
catch handles exceptions from the upstream flow only (producer and operators above it). It does not catch exceptions thrown in the collect lambda or in operators placed below it. Inside catch you can rethrow or emit a fallback value.
What is the difference between combine and zip?
zip pairs values one-to-one, waiting for both flows and finishing when either completes. combine re-emits whenever EITHER flow emits, using each flow's latest value, so it fires on every change after both have emitted once.
buffer vs conflate vs collectLatest for a slow collector?
buffer runs producer and collector concurrently, queueing emissions. conflate keeps only the latest value, dropping intermediates the collector missed. collectLatest cancels the in-progress collector block and restarts it with each new value.
When would you use flatMapLatest over flatMapConcat or flatMapMerge?
flatMapLatest cancels the previous inner flow when a new upstream value arrives, ideal for search-as-you-type. flatMapConcat processes inner flows sequentially in order; flatMapMerge collects them concurrently without ordering guarantees.
How do retry and debounce/distinctUntilChanged help on Android?
retry(n) { predicate } re-collects the upstream when an exception matches the predicate (retryWhen also gives the attempt index). debounce drops emissions until a quiet window passes (typing); distinctUntilChanged suppresses consecutive duplicate values to avoid redundant work.

Back to Flow & Operators