Callbacks and Kotlin Flows

Photo by Antoine Barrès on Unsplash

Single-shot callback

interface Operation<T> {
fun performAsync(callback: (T?, Throwable?) -> Unit)
}
suspend fun <T> Operation<T>.perform(): T =
suspendCoroutine { continuation ->
performAsync { value, exception ->
when
{
exception != null -> // operation had failed
continuation.resumeWithException(exception)
else -> // succeeded, there is a value
continuation.resume(value as T)
}
}
}

Cancellable operation

interface Operation<T> {
fun performAsync(callback: (T?, Throwable?) -> Unit)
fun cancel() // cancels ongoing operation
}
suspend fun <T> Operation<T>.perform(): T =
suspendCancellableCoroutine { continuation ->
performAsync { /* ... as before ... */ }
continuation.invokeOnCancellation { cancel() }
}

Multi-shot callback

fun <T : Any> Operation<T>.perform(): Flow<T> =
callbackFlow {
performAsync { value, exception ->
when
{
exception != null -> // operation had failed
close(exception)
value == null -> // operation had succeeded
close()
else -> // there is a value
offer(value as T)
}
}
awaitClose { cancel() }
}

Backpressure

Conflation

Reactive streams

Further reading and footnotes

  1. ^ Blocking threads, suspending coroutines explains practical difference between blocking and suspension.
  2. ^ Extension-oriented design highlights design philosophy behind extension functions.
  3. ^ Coroutines design document has more details on callbacks and suspension.
  4. ^ Cold flows, hot channels defines the concept of a cold data source.
  5. ^ Simple design of Kotlin Flow gives the basics of flows.
  6. ^ Kotlin Flows and coroutines shows the conceptual implementation of buffer operator.
  7. ^ Reactive Streams and Kotlin Flows emphasises the similarities between reactive streams and Kotlin flows.

--

--

--

Project Lead for the Kotlin Programming Language @JetBrains

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

🐘+🦀+🕸 php-ext-wasm: Migrating from wasmi to Wasmer

Introduction to No Sql Database

Thanks again @joesrosemont!! See you tonight @joesonweedst!

5 Misconceptions About Kanban

Blue Team: Port Forwarding Detection!

Postfix in Azure VMSS + automated scaling : DNS resolver failed

Ubuntu desktop on Raspberry Pi 4

Let’s Django! — First Steps into Django Web Development

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Roman Elizarov

Roman Elizarov

Project Lead for the Kotlin Programming Language @JetBrains

More from Medium

Fused Location Provider in Kotlin

👨🏼‍💻 All About Kotlin Inline(Value) Class

A Curious Tale of Late Initialisation Options — Part II

How and When to convert a Utility function in Kotlin to an Extension Function