Skip to content

Instantly share code, notes, and snippets.

@mortezae
Forked from pygy/cancelPromise.md
Created February 17, 2020 13:08
Show Gist options
  • Save mortezae/05315d8d75a2382be6935c56720121ab to your computer and use it in GitHub Desktop.
Save mortezae/05315d8d75a2382be6935c56720121ab 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