Last active
August 29, 2015 14:18
-
-
Save WebReflection/0ca8fac8013f76fb4d06 to your computer and use it in GitHub Desktop.
An alternative playground with cancel-able Promises that rejects through arbitrary value
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 | |
OP = Original.prototype; | |
if ('cancel' in OP) return; | |
var | |
OP, | |
$then = OP.then, | |
$catch = OP.catch, | |
defineProperty = Object.defineProperty, | |
defineProperties = Object.defineProperties, | |
// noop = function () {}, | |
createDescriptors = function (cancel) { | |
var descriptors = { | |
'cancel': {value: function () { | |
// this.catch(noop); | |
return cancel.apply(this, arguments); | |
}}, | |
'then': {value: function (ok, err) { | |
var args = arguments.length === 2 ? [ok, err] : [ok]; | |
if (typeof ok === 'function') args[0] = function () { | |
var r = ok.apply(this, arguments); | |
if ( | |
r instanceof Original && | |
r.hasOwnProperty('cancel') | |
) { | |
cancel = r.cancel; | |
} | |
return r; | |
}; | |
return defineProperties( | |
$then.apply(this, args), | |
descriptors | |
); | |
}}, | |
'catch': {value: function () { | |
return defineProperties( | |
$catch.apply(this, arguments), | |
descriptors | |
); | |
}} | |
}; | |
return descriptors; | |
} | |
; | |
function Promise(callback) { | |
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 (typeof howToCancel !== 'function') { | |
throw new Error('Unable to cancel this promise'); | |
} | |
return cancel || (cancel = function () { | |
if (state === 'pending') { | |
state = 'canceled'; | |
howToCancel.apply(this, arguments); | |
reject.apply(this, arguments); | |
return this; | |
} | |
}); | |
} | |
); | |
return cancel ? defineProperties(p, createDescriptors(cancel)) : p; | |
} | |
Object.getOwnPropertyNames(Original).forEach(function (name) { | |
if (!(name in Promise)) { | |
defineProperty( | |
Promise, | |
name, | |
Object.getOwnPropertyDescriptor(Original, name) | |
); | |
} | |
}); | |
Promise.prototype = OP; | |
defineProperty(OP, 'cancel', { | |
configurable: true, | |
enumerable: false, | |
writable: true, | |
value: function () { return this; } | |
}); | |
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