So I have a LiveData that I transform to an async function that takes a while to execute (like 2 seconds sometimes, or 4 seconds).
sometimes the call takes long, and sometimes it's really fast (depends on the results) sometimes it's instant (empty result)
the problem is that if I have 2 consecutive emits in my LiveData, sometimes the first result takes a while to execute, and the second one will take an instant, than it will show the second before the first, and than overwrite the result with the earlier calculation,
what I want is mroe of a sequential effect. (kinda like RxJava concatMap)
private val _state = query.mapAsync(viewModelScope) { searchString ->
if (searchString.isEmpty()) {
NoSearch
} else {
val results = repo.search(searchString)
if (results.isNotEmpty()) {
Results(results.map { mapToMainResult(it, searchString) })
} else {
NoResults
}
}
}
@MainThread
fun <X, Y> LiveData<X>.mapAsync(
scope: CoroutineScope,
mapFunction: androidx.arch.core.util.Function<X, Y>
): LiveData<Y> {
val result = MediatorLiveData<Y>()
result.addSource(this) { x ->
scope.launch(Dispatchers.IO) { result.postValue(mapFunction.apply(x)) }
}
return result
}
how do I prevent the second result from overwriting the first result?
@MainThread
fun <X, Y> LiveData<X>.mapAsync(
scope: CoroutineScope,
mapFunction: (X) -> Y,
): LiveData<Y> = switchMap { value ->
liveData(scope.coroutineContext) {
withContext(Dispatchers.IO) {
emit(mapFunction(value))
}
}
}