Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active August 29, 2015 14:18
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 WebReflection/1a87023b4f31a15b18da to your computer and use it in GitHub Desktop.
Save WebReflection/1a87023b4f31a15b18da to your computer and use it in GitHub Desktop.
An alternative playground with cancel-able Promises without chainability
(function (Object, Original) {'use strict';
// (C) Andrea Giammarchi - WTFPL
if ('cancelable' in Original.prototype) return;
var
defineProperties = Object.defineProperties,
error = function () {
return new Error('Operation not permitted');
}
;
function Promise(callback) {
if (!this) throw error();
var
resolve, reject, cancel,
state = 'pending',
p = new Original(function ($resolve, $reject) {
resolve = $resolve;
reject = $reject;
})
;
callback(
function () {
if (state === 'pending') {
state = 'resolved';
resolve.apply(this, arguments);
}
},
function () {
if (state === 'pending') {
state = 'rejected';
reject.apply(this, arguments);
}
},
function (howToCancel) {
if (
// if cancel-ability is defined, it cannot be redefined
typeof cancel === 'function' ||
// also if the way to cancel is not a function, throw
typeof howToCancel !== 'function'
) {
throw error();
}
// once `p.cancel()` will be eventually invoked
cancel = function () {
// if it's not resolved yet
if (state === 'pending') {
// block resolve/reject
state = 'canceled';
// invoke its cancelability (try/catch?)
howToCancel.apply(this, arguments);
// stop pending and reject
reject.apply(this, arguments);
}
return p;
};
// give the Promise scope the ability
// to auto-cancel through the same function
return cancel;
}
);
// in case cancel-ability has been defined
return typeof cancel === 'function' ?
// setup Promise cancel-ability
defineProperties(p, {
cancel: {value: cancel},
cancelable: {value: true}
}) :
// otherwise drop the ability to lazily define cancel
(cancel = Object), p;
}
// add .all .race and any other to the new Promise constructor
Object.getOwnPropertyNames(Original).forEach(function (name) {
if (!(name in Promise)) {
Object.defineProperty(
Promise,
name,
Object.getOwnPropertyDescriptor(Original, name)
);
}
});
// TBD: set cancelable false by default
defineProperties(
(Promise.prototype = Original.prototype),
{cancelable: {value: false}}
);
try { module.exports = Promise; }
catch(e) { this.Promise = Promise; }
}.call(this, Object, Promise));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment