withProgress

fun <T> Deferred<T>.withProgress(progress: StateFlow<Progress>): ProgressFuture<T>

Joins a Deferred and a progress flow that you already have into one ProgressFuture.

Use it for an API that reports progress through a callback, such as a Ktor download with onDownload.

val state = MutableStateFlow(Progress(null, "downloading"))
val download = scope.async {
client.get(url) {
onDownload { sent, total ->
val fraction = total?.let { sent.toFloat() / it }
state.value = Progress(fraction, "downloading")
}
}.body<ByteArray>()
}.withProgress(state)

Watch out

  • This function never changes progress. Unlike asyncWithProgress, it does not set 1f on success. Your own code sets every value.

Parameters

progress

the flow that ProgressFuture.progress returns, unchanged.