Here’s my take.
The proper cancellation logic of pending asynchronous operations is an important consideration while designing the front-end, and it can also improve the scalability of the back-end.
For example, consider Autocomplete:
user types a character, we start an async delay (e.g., via
when they delay is completed, we start an async fetch that returns a promise;
meanwhile user is typing another character, while we still haven’t received the server’s response for the previous fetch;
ideally, we now need to cancel the fetch (or the delay, whatever is pending), before we start a new sequence of async calls. E.g., see the
delayWithCancellationfrom the title link;
on the server, we most likely also want to cancel the pending API call to another micro-service that we use for auto-completion;
now we can start another delay and the fetch, and so on.
Thus, cancellation is pervasive through all code layers, similar to
In a nutshell, it deals with two concepts:
the Cancellation Source. This is the “producer” part of the API, the code which triggers cancellation and it’s normally external to the asynchronous operation itself.
the Cancellation Token. This is the “consumer” part of the API, that lets the code which conducts the async operation itself to observe the request to cancel it and act properly. Think of
addEventListenerfor the hypothetical
cancelevent. Back to the Autocomplete example, we may want to call
clearTimerfor the delay, or
AbortController.abortfor the HTTP fetch.
The GitHub issue I referenced here is just yet another attempt at that, my own modest take with custom
CancellablePromise class that extends the standard
Promise and uses Rob’s
Prex library for
CancellationToken. It’s been great to get some feedback from Rob, and I hope the discussion will continue.
For a complete example, here’s a RunKit.