Skip to content

Instantly share code, notes, and snippets.

@tracker1
Created July 8, 2017 00:26
Show Gist options
  • Save tracker1/3d786ff762e0f6202d5a3efb406cfb91 to your computer and use it in GitHub Desktop.
Save tracker1/3d786ff762e0f6202d5a3efb406cfb91 to your computer and use it in GitHub Desktop.
JavaScript Cancelable Promise
var CancelablePromise = (function(){
var cancelledPromiseSymbol = Symbol('PROMISE_CANCELLED');
function createTypeError(message) {
var error = new TypeError(message);
var stack = error.stack.split('\n');
stack.splice(1, 1);
stack[1] = stack[1].replace(/:\d+:\d+\)$/, ')');
error.stack = stack.join('\n');
throw error;
}
function CancelablePromise(callback) {
if (!(this instanceof CancelablePromise)) {
throw createTypeError('undefined is not a cancelable promise');
}
if (typeof callback !== 'function') {
throw createTypeError('Promise resolver ' + String(callback) + ' is not a function');
}
var resolve;
var reject;
var cancelMethod = undefined;
var returnPromise = new Promise(function(res, rej) {
resolve = res;
reject = rej;
});
returnPromise.cancel = function() {
if (!cancelMethod) reject(cancelledPromiseSymbol);
Promise.resolve().then({ then: cancelMethod }).then(resolve, reject);
};
var onCancel = function(cb) {
if (typeof cb !== 'function') {
throw createTypeError('Promise onCancel handler ' + String(cb) + ' is not a function');
}
cancelMethod = cb;
};
callback(resolve, reject, onCancel);
return returnPromise;
};
CancelablePromise.name = 'Promise';
CancelablePromise.prototype = Promise.prototype;
CancelablePromise.CANCELLED = cancelledPromiseSymbol;
CancelablePromise.resolve = Promise.resolve;
CancelablePromise.reject = Promise.reject;
CancelablePromise.race = Promise.race;
return CancelablePromise;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment