Kotlin / kotlinx.coroutines

Library support for Kotlin coroutines
Apache License 2.0
12.95k stars 1.84k forks source link

Support cancellation in window.fetch #3390

Open vlsi opened 2 years ago

vlsi commented 2 years ago

It would be great if window.fetch supported cancellation via AbortController: https://developer.chrome.com/blog/abortable-fetch.

I would expect that if coroutine is canceled, then fetch should be canceled as well automatically.

In other words, the following extension would be great to have:

suspend fun fetch(input: dynamic, init: RequestInit = jso {}) : Response {
    if (init.signal != null) {
        // Abort signal is already set, we can't have two, so just wait for the fetch to complete
        return window.fetch(input, init).await()
    }

    // Setup AbortController so the fetch is cancelled if coroutine is cancelled
    val controller = AbortController()
    init.signal = controller.signal
    return window.fetch(input, init).let { promise ->
        suspendCancellableCoroutine { cont ->
            cont.invokeOnCancellation { controller.abort() }
            promise.then(
                onFulfilled = { cont.resume(it) },
                onRejected = { cont.resumeWithException(it) }
            )
        }
    }
}

This implementation depends on suspendCancellableCoroutine, so it looks like the change can't be handled via kotlin-stdlib-js alone.

WDYT?


The current type for window.fetch returns Promise, and it has no Async in the function name: https://github.com/JetBrains/kotlin/blob/9bec1a635845ff9336e831a589cdfb3413243d44/libraries/stdlib/api/js/org.w3c.dom.kt#L9209 It seems to violate the naming rule of functions doing computations in background.

It would be nice if the mapping could be reworked so window.fetch becomes suspending blocking function, and the one that returns Promise becomes window.fetchAsync

See also:

qwwdfsad commented 2 years ago

We're still deciding how to proceed with active development of coroutines on JS, so this is on hold right now

turansky commented 1 month ago

Suspend fetch with cancellation on board!