Skip to content

Instantly share code, notes, and snippets.

@pluma
Last active May 5, 2016 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pluma/62c232dde2eb301b9de476c587574911 to your computer and use it in GitHub Desktop.
Save pluma/62c232dde2eb301b9de476c587574911 to your computer and use it in GitHub Desktop.
/*global assert*/
class CancellationError extends Error {}
CancellationError.prototype.name = 'CancellationError'
function deferred () {
let _resolve, _reject
const promise = new Promise((resolve, reject) => {
_resolve = resolve
_reject = reject
})
return {promise, resolve: _resolve, reject: _reject}
}
function cancellable (fn) {
let cancel
let cancelled = false
let d = deferred()
const cancellation = new Promise((resolve, reject) => {
d.promise.then(() => resolve(), () => resolve())
cancel = (reason) => {
cancelled = true
if (reason) assert.equal(typeof reason, 'string')
reject(new CancellationError(reason || 'cancelled'))
}
})
fn(cancellation, () => cancelled).then(d.resolve, d.reject)
return Object.assign(d.promise, {cancel})
}
function somethingAsync () {
return cancellable((cancellation, cancelled) => new Promise((resolve, reject) => {
const start = Date.now()
let timeout
cancellation.catch((err) => {
clearTimeout(timeout)
console.log(`Cancelled after ${Date.now() - start}ms`)
reject(err)
})
timeout = setTimeout(() => {
console.log(`Resolving after ${Date.now() - start}ms`)
resolve('two seconds have passed')
}, 2000)
}))
}
let p = somethingAsync()
p.then(console.log, console.error)
p.cancel()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment