Last active
August 29, 2015 14:18
-
-
Save WebReflection/1a87023b4f31a15b18da to your computer and use it in GitHub Desktop.
An alternative playground with cancel-able Promises without chainability
This file contains 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
(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