Skip to content

Instantly share code, notes, and snippets.

@g3tr1ght
Forked from pygy/cancelPromise.md
Created November 6, 2021 05:06
Show Gist options
  • Select an option

  • Save g3tr1ght/7db2ad1b6a9e1411e2cda48305ceb688 to your computer and use it in GitHub Desktop.

Select an option

Save g3tr1ght/7db2ad1b6a9e1411e2cda48305ceb688 to your computer and use it in GitHub Desktop.
You can already cancel ES6 Promises

The gist: by having a Promise adopt the state of a forever pending one, you can suspend its then handlers chain.

Promise.pending = Promise.race.bind(Promise, [])

let cancel

new Promise(function(fulfill, reject) {
  cancel = function() {fulfill(Promise.pending())}
  setTimeout(fulfill, 1000, 5)
}).then(console.log)

cancel() // 5 is never logged.

Also, mid-chain:

someAsyncJob().then(result => {
  if (result === 'enough') return Promise.pending()
  return moreAsyncWork()
}).then(otherResult => {
  // won't run if result was 'enough'
})

Possible implementations/API:

Taking a page fron Bluebird (but without canceling parents up the chain)

function cancellablePromise(executor) {
  let cancel
  var res = new Promise(function(fulfill, reject) {
    let handler
    function onCancel(cb) {handler = cb}
    cancel = function cancel() {
      fulfill(Promise.pending()) // adopt a forever pending state
      if (typeof handler === 'function') handler()
    }
    executor(fulfill, reject, onCancel)
  })
  res.cancel = cancel
  return res
}

Alternatively

function cancellablePromise(executor) {
  return new Promise(function(fulfill, reject) {
    function cancel() {fulfill(Promise.pending())}
    executor(fulfill, reject, cancel)
  })
}

Given all the hubub around cancellable promises, I'm sure I'm missing something...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment