mapLatest(), at its core, works like
map(): you give
mapLatest() a lambda
expression or other function type, and
mapLatest() invokes that lambda for
every upstream item and emits whatever the lambda returns.
map(), however, is designed for fast operations. That is not always your use case.
For example, suppose that you have a search field, and searching involves
a database query or a Web service call. You want to show search results as
the user types, so you apply a
debounce() operator to a
the user input. But the user might type faster than the database or Web service
handles the search. In that case, once you get the updated search expression,
you want to cancel any outstanding search operation and start a new one.
That is what
mapLatest() is for.
The lambda expression can call
suspend functions, such as for I/O. If the
lambda expression evaluates to a value before the upstream
Flow emits something
new, whatever the lambda evaluates to is emitted downstream. However, if the
Flow does emit something while the lambda is still doing work,
the coroutine invoking the lambda expression is cancelled, and the lambda
is re-invoked with the new value.
In this sample, you will only see
Result for 4 in the output. While the
debounce(250) operator will emit values for both
4 will be
emitted before the
mapLatest() lambda completes its
delay(), so the
invocation of the lambda is cancelled. If you remove or comment out that
call, though, you will see
Result for 3 and
Result for 4.