Canceling promises

Updated . Posted . Visible to the public. Repeats.

The standard way to abort async code is that your function takes a AbortSignal Show archive.org snapshot { signal } property. The caller can use this signal to send an abort request to your function. Upon receiving the request, your function should reject its promise with an error.

Async browser functions like fetch() reject their promises with a new DOMException('Message here', 'AbortError') when canceled.

This already has good browser support and can be polyfilled on older browsers.

Example

Here is an async function countDown(). It returns a promise that will be fulfilled after the given number of seconds:

function countDown(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, seconds * 1000)  
  })
}

Here is how you would use it:

countDown(10).then(() => console.log("10 seconds have passed"))

// prints "10 seconds have passed" after 10 seconds

Making countDown() abortable

Here is a variant of countDown() that may be canceled by the caller before the time has elapsed:

function countDown(seconds, options = {}) {
  return new Promise((resolve, reject) => {
    if (options.signal) {
      options.signal.addEventListener('abort', (event) => {
        reject(new DOMException('User aborted countdown', 'AbortError'))
      })
    }
  
    setTimeout(resolve, seconds * 1000)  
  })
}

You use it by passing an AbortSignal as a { signal } option and abort it manually by using an AbortController Show archive.org snapshot :

let controller = new AbortController()

countDown(10, { signal: controller.signal }).then(
  () => console.log("10 seconds have passed"),
  (reason) => console.log("Countdown failed:", reason)
)

controller.abort()

/* prints "Coundown failed: User aborted countdown" in the next microtask */

Note that throwing a DOMException Show archive.org snapshot will guarantee compatibility with how the browser's API deals with promise abortion.

Henning Koch
Last edit
Paul Demel
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2018-12-29 05:01)