Skip to content

Instantly share code, notes, and snippets.

@thedang
Forked from pygy/cancelPromise.md
Created December 19, 2016 03:57
Show Gist options
  • Save thedang/3e9aea575325a603afafe23afdfd9b8e to your computer and use it in GitHub Desktop.
Save thedang/3e9aea575325a603afafe23afdfd9b8e 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.

const foreverPending = new Promise(function() {});

let cancel

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

cancel() // 5 is never logged.

Also, mid-chain:

someAsyncJob().then(result => {
  if (result === 'enough') return foreverPending
  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(foreverPending) // adopt a forever pending state
      if (typeof handler === 'function') handler()
    }
    executor(fulfill, reject, onCancel)
  })
  res.cancel = cancel
  return res
}

Alternatively

let foreverPending = new Promise(function() {});

function cancellablePromise(executor) {
  return new Promise(function(fulfill, reject) {
    function cancel() {fulfill(foreverPending)} // adopt a forever pending state
    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