Last active
May 5, 2016 15:40
-
-
Save pluma/62c232dde2eb301b9de476c587574911 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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