Comparing version 7.0.0 to 7.0.1
@@ -66,5 +66,5 @@ 'use strict'; | ||
var out = fixup(src); | ||
out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\)/g, ''); | ||
out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\);/g, ''); | ||
out = out.replace(/asap/g, "setImmediate"); | ||
fs.writeFileSync(__dirname + '/setimmediate/' + filename, out); | ||
}); |
'use strict'; | ||
var asap = require('asap') | ||
var asap = require('asap'); | ||
function noop() {}; | ||
function noop() {} | ||
@@ -53,96 +53,109 @@ // States: | ||
module.exports = Promise; | ||
function Promise(fn) { | ||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') | ||
if (typeof fn !== 'function') throw new TypeError('not a function') | ||
this._71 = 0; | ||
this._18 = null; | ||
this._61 = []; | ||
if (typeof this !== 'object') { | ||
throw new TypeError('Promises must be constructed via new'); | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new TypeError('not a function'); | ||
} | ||
this._32 = 0; | ||
this._8 = null; | ||
this._89 = []; | ||
if (fn === noop) return; | ||
doResolve(fn, this); | ||
} | ||
Promise.prototype._10 = function (onFulfilled, onRejected) { | ||
var self = this; | ||
return new this.constructor(function (resolve, reject) { | ||
Promise._83 = noop; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) { | ||
return safeThen(this, onFulfilled, onRejected); | ||
} | ||
var res = new Promise(noop); | ||
handle(this, new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
function safeThen(self, onFulfilled, onRejected) { | ||
return new self.constructor(function (resolve, reject) { | ||
var res = new Promise(noop); | ||
res.then(resolve, reject); | ||
self._24(new Handler(onFulfilled, onRejected, res)); | ||
handle(self, new Handler(onFulfilled, onRejected, res)); | ||
}); | ||
}; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) return this._10(onFulfilled, onRejected); | ||
var res = new Promise(noop); | ||
this._24(new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
Promise.prototype._24 = function(deferred) { | ||
if (this._71 === 3) { | ||
this._18._24(deferred); | ||
return; | ||
function handle(self, deferred) { | ||
while (self._32 === 3) { | ||
self = self._8; | ||
} | ||
if (this._71 === 0) { | ||
this._61.push(deferred); | ||
if (self._32 === 0) { | ||
self._89.push(deferred); | ||
return; | ||
} | ||
var state = this._71; | ||
var value = this._18; | ||
asap(function() { | ||
var cb = state === 1 ? deferred.onFulfilled : deferred.onRejected | ||
var cb = self._32 === 1 ? deferred.onFulfilled : deferred.onRejected; | ||
if (cb === null) { | ||
(state === 1 ? deferred.promise._82(value) : deferred.promise._67(value)) | ||
return | ||
if (self._32 === 1) { | ||
resolve(deferred.promise, self._8); | ||
} else { | ||
reject(deferred.promise, self._8); | ||
} | ||
return; | ||
} | ||
var ret = tryCallOne(cb, value); | ||
var ret = tryCallOne(cb, self._8); | ||
if (ret === IS_ERROR) { | ||
deferred.promise._67(LAST_ERROR) | ||
reject(deferred.promise, LAST_ERROR); | ||
} else { | ||
deferred.promise._82(ret) | ||
resolve(deferred.promise, ret); | ||
} | ||
}); | ||
}; | ||
Promise.prototype._82 = function(newValue) { | ||
//Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === this) { | ||
return this._67(new TypeError('A promise cannot be resolved with itself.')) | ||
} | ||
function resolve(self, newValue) { | ||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === self) { | ||
return reject( | ||
self, | ||
new TypeError('A promise cannot be resolved with itself.') | ||
); | ||
} | ||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { | ||
if ( | ||
newValue && | ||
(typeof newValue === 'object' || typeof newValue === 'function') | ||
) { | ||
var then = getThen(newValue); | ||
if (then === IS_ERROR) { | ||
return this._67(LAST_ERROR); | ||
return reject(self, LAST_ERROR); | ||
} | ||
if ( | ||
then === this.then && | ||
newValue instanceof Promise && | ||
newValue._24 === this._24 | ||
then === self.then && | ||
newValue instanceof Promise | ||
) { | ||
this._71 = 3; | ||
this._18 = newValue; | ||
for (var i = 0; i < this._61.length; i++) { | ||
newValue._24(this._61[i]); | ||
} | ||
self._32 = 3; | ||
self._8 = newValue; | ||
finale(self); | ||
return; | ||
} else if (typeof then === 'function') { | ||
doResolve(then.bind(newValue), this) | ||
return | ||
doResolve(then.bind(newValue), self); | ||
return; | ||
} | ||
} | ||
this._71 = 1 | ||
this._18 = newValue | ||
this._94() | ||
self._32 = 1; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._67 = function (newValue) { | ||
this._71 = 2 | ||
this._18 = newValue | ||
this._94() | ||
function reject(self, newValue) { | ||
self._32 = 2; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._94 = function () { | ||
for (var i = 0; i < this._61.length; i++) | ||
this._24(this._61[i]) | ||
this._61 = null | ||
function finale(self) { | ||
for (var i = 0; i < self._89.length; i++) { | ||
handle(self, self._89[i]); | ||
} | ||
self._89 = null; | ||
} | ||
function Handler(onFulfilled, onRejected, promise){ | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null; | ||
this.promise = promise; | ||
@@ -160,14 +173,14 @@ } | ||
var res = tryCallTwo(fn, function (value) { | ||
if (done) return | ||
done = true | ||
promise._82(value) | ||
if (done) return; | ||
done = true; | ||
resolve(promise, value); | ||
}, function (reason) { | ||
if (done) return | ||
done = true | ||
promise._67(reason) | ||
if (done) return; | ||
done = true; | ||
reject(promise, reason); | ||
}) | ||
if (!done && res === IS_ERROR) { | ||
done = true | ||
promise._67(LAST_ERROR) | ||
done = true; | ||
reject(promise, LAST_ERROR); | ||
} | ||
} | ||
} |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype.done = function (onFulfilled, onRejected) { | ||
var self = arguments.length ? this.then.apply(this, arguments) : this | ||
var self = arguments.length ? this.then.apply(this, arguments) : this; | ||
self.then(null, function (err) { | ||
setTimeout(function () { | ||
throw err | ||
}, 0) | ||
}) | ||
} | ||
throw err; | ||
}, 0); | ||
}); | ||
}; |
@@ -5,73 +5,77 @@ 'use strict'; | ||
var Promise = require('./core.js') | ||
var asap = require('asap') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
/* Static Functions */ | ||
function ValuePromise(value) { | ||
this.then = function (onFulfilled) { | ||
if (typeof onFulfilled !== 'function') return this | ||
return new Promise(function (resolve, reject) { | ||
asap(function () { | ||
try { | ||
resolve(onFulfilled(value)) | ||
} catch (ex) { | ||
reject(ex); | ||
} | ||
}) | ||
}) | ||
} | ||
var TRUE = valuePromise(true); | ||
var FALSE = valuePromise(false); | ||
var NULL = valuePromise(null); | ||
var UNDEFINED = valuePromise(undefined); | ||
var ZERO = valuePromise(0); | ||
var EMPTYSTRING = valuePromise(''); | ||
function valuePromise(value) { | ||
var p = new Promise(Promise._83); | ||
p._32 = 1; | ||
p._8 = value; | ||
return p; | ||
} | ||
ValuePromise.prototype = Promise.prototype | ||
var TRUE = new ValuePromise(true) | ||
var FALSE = new ValuePromise(false) | ||
var NULL = new ValuePromise(null) | ||
var UNDEFINED = new ValuePromise(undefined) | ||
var ZERO = new ValuePromise(0) | ||
var EMPTYSTRING = new ValuePromise('') | ||
Promise.resolve = function (value) { | ||
if (value instanceof Promise) return value | ||
if (value instanceof Promise) return value; | ||
if (value === null) return NULL | ||
if (value === undefined) return UNDEFINED | ||
if (value === true) return TRUE | ||
if (value === false) return FALSE | ||
if (value === 0) return ZERO | ||
if (value === '') return EMPTYSTRING | ||
if (value === null) return NULL; | ||
if (value === undefined) return UNDEFINED; | ||
if (value === true) return TRUE; | ||
if (value === false) return FALSE; | ||
if (value === 0) return ZERO; | ||
if (value === '') return EMPTYSTRING; | ||
if (typeof value === 'object' || typeof value === 'function') { | ||
try { | ||
var then = value.then | ||
var then = value.then; | ||
if (typeof then === 'function') { | ||
return new Promise(then.bind(value)) | ||
return new Promise(then.bind(value)); | ||
} | ||
} catch (ex) { | ||
return new Promise(function (resolve, reject) { | ||
reject(ex) | ||
}) | ||
reject(ex); | ||
}); | ||
} | ||
} | ||
return valuePromise(value); | ||
}; | ||
return new ValuePromise(value) | ||
} | ||
Promise.all = function (arr) { | ||
var args = Array.prototype.slice.call(arr) | ||
var args = Array.prototype.slice.call(arr); | ||
return new Promise(function (resolve, reject) { | ||
if (args.length === 0) return resolve([]) | ||
var remaining = args.length | ||
if (args.length === 0) return resolve([]); | ||
var remaining = args.length; | ||
function res(i, val) { | ||
if (val && (typeof val === 'object' || typeof val === 'function')) { | ||
var then = val.then | ||
if (typeof then === 'function') { | ||
then.call(val, function (val) { res(i, val) }, reject) | ||
return | ||
if (val instanceof Promise && val.then === Promise.prototype.then) { | ||
while (val._32 === 3) { | ||
val = val._8; | ||
} | ||
if (val._32 === 1) return res(i, val._8); | ||
if (val._32 === 2) reject(val._8); | ||
val.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} else { | ||
var then = val.then; | ||
if (typeof then === 'function') { | ||
var p = new Promise(then.bind(val)); | ||
p.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} | ||
} | ||
} | ||
args[i] = val | ||
args[i] = val; | ||
if (--remaining === 0) { | ||
@@ -82,20 +86,20 @@ resolve(args); | ||
for (var i = 0; i < args.length; i++) { | ||
res(i, args[i]) | ||
res(i, args[i]); | ||
} | ||
}) | ||
} | ||
}); | ||
}; | ||
Promise.reject = function (value) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
reject(value); | ||
}); | ||
} | ||
}; | ||
Promise.race = function (values) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
values.forEach(function(value){ | ||
Promise.resolve(value).then(resolve, reject); | ||
}) | ||
}); | ||
}); | ||
} | ||
}; | ||
@@ -106,2 +110,2 @@ /* Prototype Methods */ | ||
return this.then(null, onRejected); | ||
} | ||
}; |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype['finally'] = function (f) { | ||
return this.then(function (value) { | ||
return Promise.resolve(f()).then(function () { | ||
return value | ||
}) | ||
return value; | ||
}); | ||
}, function (err) { | ||
return Promise.resolve(f()).then(function () { | ||
throw err | ||
}) | ||
}) | ||
} | ||
throw err; | ||
}); | ||
}); | ||
}; |
'use strict'; | ||
module.exports = require('./core.js') | ||
require('./done.js') | ||
require('./finally.js') | ||
require('./es6-extensions.js') | ||
require('./node-extensions.js') | ||
module.exports = require('./core.js'); | ||
require('./done.js'); | ||
require('./finally.js'); | ||
require('./es6-extensions.js'); | ||
require('./node-extensions.js'); |
'use strict'; | ||
//This file contains then/promise specific extensions that are only useful for node.js interop | ||
// This file contains then/promise specific extensions that are only useful | ||
// for node.js interop | ||
var Promise = require('./core.js') | ||
var asap = require('asap') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
@@ -13,17 +14,23 @@ /* Static Functions */ | ||
Promise.denodeify = function (fn, argumentCount) { | ||
argumentCount = argumentCount || Infinity | ||
argumentCount = argumentCount || Infinity; | ||
return function () { | ||
var self = this | ||
var args = Array.prototype.slice.call(arguments) | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
return new Promise(function (resolve, reject) { | ||
while (args.length && args.length > argumentCount) { | ||
args.pop() | ||
args.pop(); | ||
} | ||
args.push(function (err, res) { | ||
if (err) reject(err) | ||
else resolve(res) | ||
if (err) reject(err); | ||
else resolve(res); | ||
}) | ||
var res = fn.apply(self, args) | ||
if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') { | ||
resolve(res) | ||
var res = fn.apply(self, args); | ||
if (res && | ||
( | ||
typeof res === 'object' || | ||
typeof res === 'function' | ||
) && | ||
typeof res.then === 'function' | ||
) { | ||
resolve(res); | ||
} | ||
@@ -35,13 +42,16 @@ }) | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null | ||
var ctx = this | ||
var args = Array.prototype.slice.call(arguments); | ||
var callback = | ||
typeof args[args.length - 1] === 'function' ? args.pop() : null; | ||
var ctx = this; | ||
try { | ||
return fn.apply(this, arguments).nodeify(callback, ctx) | ||
return fn.apply(this, arguments).nodeify(callback, ctx); | ||
} catch (ex) { | ||
if (callback === null || typeof callback == 'undefined') { | ||
return new Promise(function (resolve, reject) { reject(ex) }) | ||
return new Promise(function (resolve, reject) { | ||
reject(ex); | ||
}); | ||
} else { | ||
asap(function () { | ||
callback.call(ctx, ex) | ||
callback.call(ctx, ex); | ||
}) | ||
@@ -54,13 +64,13 @@ } | ||
Promise.prototype.nodeify = function (callback, ctx) { | ||
if (typeof callback != 'function') return this | ||
if (typeof callback != 'function') return this; | ||
this.then(function (value) { | ||
asap(function () { | ||
callback.call(ctx, null, value) | ||
}) | ||
callback.call(ctx, null, value); | ||
}); | ||
}, function (err) { | ||
asap(function () { | ||
callback.call(ctx, err) | ||
}) | ||
}) | ||
callback.call(ctx, err); | ||
}); | ||
}); | ||
} |
155
lib/core.js
'use strict'; | ||
var asap = require('asap/raw') | ||
var asap = require('asap/raw'); | ||
function noop() {}; | ||
function noop() {} | ||
@@ -53,96 +53,109 @@ // States: | ||
module.exports = Promise; | ||
function Promise(fn) { | ||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') | ||
if (typeof fn !== 'function') throw new TypeError('not a function') | ||
this._71 = 0; | ||
this._18 = null; | ||
this._61 = []; | ||
if (typeof this !== 'object') { | ||
throw new TypeError('Promises must be constructed via new'); | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new TypeError('not a function'); | ||
} | ||
this._32 = 0; | ||
this._8 = null; | ||
this._89 = []; | ||
if (fn === noop) return; | ||
doResolve(fn, this); | ||
} | ||
Promise.prototype._10 = function (onFulfilled, onRejected) { | ||
var self = this; | ||
return new this.constructor(function (resolve, reject) { | ||
Promise._83 = noop; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) { | ||
return safeThen(this, onFulfilled, onRejected); | ||
} | ||
var res = new Promise(noop); | ||
handle(this, new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
function safeThen(self, onFulfilled, onRejected) { | ||
return new self.constructor(function (resolve, reject) { | ||
var res = new Promise(noop); | ||
res.then(resolve, reject); | ||
self._24(new Handler(onFulfilled, onRejected, res)); | ||
handle(self, new Handler(onFulfilled, onRejected, res)); | ||
}); | ||
}; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) return this._10(onFulfilled, onRejected); | ||
var res = new Promise(noop); | ||
this._24(new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
Promise.prototype._24 = function(deferred) { | ||
if (this._71 === 3) { | ||
this._18._24(deferred); | ||
return; | ||
function handle(self, deferred) { | ||
while (self._32 === 3) { | ||
self = self._8; | ||
} | ||
if (this._71 === 0) { | ||
this._61.push(deferred); | ||
if (self._32 === 0) { | ||
self._89.push(deferred); | ||
return; | ||
} | ||
var state = this._71; | ||
var value = this._18; | ||
asap(function() { | ||
var cb = state === 1 ? deferred.onFulfilled : deferred.onRejected | ||
var cb = self._32 === 1 ? deferred.onFulfilled : deferred.onRejected; | ||
if (cb === null) { | ||
(state === 1 ? deferred.promise._82(value) : deferred.promise._67(value)) | ||
return | ||
if (self._32 === 1) { | ||
resolve(deferred.promise, self._8); | ||
} else { | ||
reject(deferred.promise, self._8); | ||
} | ||
return; | ||
} | ||
var ret = tryCallOne(cb, value); | ||
var ret = tryCallOne(cb, self._8); | ||
if (ret === IS_ERROR) { | ||
deferred.promise._67(LAST_ERROR) | ||
reject(deferred.promise, LAST_ERROR); | ||
} else { | ||
deferred.promise._82(ret) | ||
resolve(deferred.promise, ret); | ||
} | ||
}); | ||
}; | ||
Promise.prototype._82 = function(newValue) { | ||
//Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === this) { | ||
return this._67(new TypeError('A promise cannot be resolved with itself.')) | ||
} | ||
function resolve(self, newValue) { | ||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === self) { | ||
return reject( | ||
self, | ||
new TypeError('A promise cannot be resolved with itself.') | ||
); | ||
} | ||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { | ||
if ( | ||
newValue && | ||
(typeof newValue === 'object' || typeof newValue === 'function') | ||
) { | ||
var then = getThen(newValue); | ||
if (then === IS_ERROR) { | ||
return this._67(LAST_ERROR); | ||
return reject(self, LAST_ERROR); | ||
} | ||
if ( | ||
then === this.then && | ||
newValue instanceof Promise && | ||
newValue._24 === this._24 | ||
then === self.then && | ||
newValue instanceof Promise | ||
) { | ||
this._71 = 3; | ||
this._18 = newValue; | ||
for (var i = 0; i < this._61.length; i++) { | ||
newValue._24(this._61[i]); | ||
} | ||
self._32 = 3; | ||
self._8 = newValue; | ||
finale(self); | ||
return; | ||
} else if (typeof then === 'function') { | ||
doResolve(then.bind(newValue), this) | ||
return | ||
doResolve(then.bind(newValue), self); | ||
return; | ||
} | ||
} | ||
this._71 = 1 | ||
this._18 = newValue | ||
this._94() | ||
self._32 = 1; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._67 = function (newValue) { | ||
this._71 = 2 | ||
this._18 = newValue | ||
this._94() | ||
function reject(self, newValue) { | ||
self._32 = 2; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._94 = function () { | ||
for (var i = 0; i < this._61.length; i++) | ||
this._24(this._61[i]) | ||
this._61 = null | ||
function finale(self) { | ||
for (var i = 0; i < self._89.length; i++) { | ||
handle(self, self._89[i]); | ||
} | ||
self._89 = null; | ||
} | ||
function Handler(onFulfilled, onRejected, promise){ | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null; | ||
this.promise = promise; | ||
@@ -160,14 +173,14 @@ } | ||
var res = tryCallTwo(fn, function (value) { | ||
if (done) return | ||
done = true | ||
promise._82(value) | ||
if (done) return; | ||
done = true; | ||
resolve(promise, value); | ||
}, function (reason) { | ||
if (done) return | ||
done = true | ||
promise._67(reason) | ||
if (done) return; | ||
done = true; | ||
reject(promise, reason); | ||
}) | ||
if (!done && res === IS_ERROR) { | ||
done = true | ||
promise._67(LAST_ERROR) | ||
done = true; | ||
reject(promise, LAST_ERROR); | ||
} | ||
} | ||
} |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype.done = function (onFulfilled, onRejected) { | ||
var self = arguments.length ? this.then.apply(this, arguments) : this | ||
var self = arguments.length ? this.then.apply(this, arguments) : this; | ||
self.then(null, function (err) { | ||
setTimeout(function () { | ||
throw err | ||
}, 0) | ||
}) | ||
} | ||
throw err; | ||
}, 0); | ||
}); | ||
}; |
@@ -5,73 +5,77 @@ 'use strict'; | ||
var Promise = require('./core.js') | ||
var asap = require('asap/raw') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap/raw'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
/* Static Functions */ | ||
function ValuePromise(value) { | ||
this.then = function (onFulfilled) { | ||
if (typeof onFulfilled !== 'function') return this | ||
return new Promise(function (resolve, reject) { | ||
asap(function () { | ||
try { | ||
resolve(onFulfilled(value)) | ||
} catch (ex) { | ||
reject(ex); | ||
} | ||
}) | ||
}) | ||
} | ||
var TRUE = valuePromise(true); | ||
var FALSE = valuePromise(false); | ||
var NULL = valuePromise(null); | ||
var UNDEFINED = valuePromise(undefined); | ||
var ZERO = valuePromise(0); | ||
var EMPTYSTRING = valuePromise(''); | ||
function valuePromise(value) { | ||
var p = new Promise(Promise._83); | ||
p._32 = 1; | ||
p._8 = value; | ||
return p; | ||
} | ||
ValuePromise.prototype = Promise.prototype | ||
var TRUE = new ValuePromise(true) | ||
var FALSE = new ValuePromise(false) | ||
var NULL = new ValuePromise(null) | ||
var UNDEFINED = new ValuePromise(undefined) | ||
var ZERO = new ValuePromise(0) | ||
var EMPTYSTRING = new ValuePromise('') | ||
Promise.resolve = function (value) { | ||
if (value instanceof Promise) return value | ||
if (value instanceof Promise) return value; | ||
if (value === null) return NULL | ||
if (value === undefined) return UNDEFINED | ||
if (value === true) return TRUE | ||
if (value === false) return FALSE | ||
if (value === 0) return ZERO | ||
if (value === '') return EMPTYSTRING | ||
if (value === null) return NULL; | ||
if (value === undefined) return UNDEFINED; | ||
if (value === true) return TRUE; | ||
if (value === false) return FALSE; | ||
if (value === 0) return ZERO; | ||
if (value === '') return EMPTYSTRING; | ||
if (typeof value === 'object' || typeof value === 'function') { | ||
try { | ||
var then = value.then | ||
var then = value.then; | ||
if (typeof then === 'function') { | ||
return new Promise(then.bind(value)) | ||
return new Promise(then.bind(value)); | ||
} | ||
} catch (ex) { | ||
return new Promise(function (resolve, reject) { | ||
reject(ex) | ||
}) | ||
reject(ex); | ||
}); | ||
} | ||
} | ||
return valuePromise(value); | ||
}; | ||
return new ValuePromise(value) | ||
} | ||
Promise.all = function (arr) { | ||
var args = Array.prototype.slice.call(arr) | ||
var args = Array.prototype.slice.call(arr); | ||
return new Promise(function (resolve, reject) { | ||
if (args.length === 0) return resolve([]) | ||
var remaining = args.length | ||
if (args.length === 0) return resolve([]); | ||
var remaining = args.length; | ||
function res(i, val) { | ||
if (val && (typeof val === 'object' || typeof val === 'function')) { | ||
var then = val.then | ||
if (typeof then === 'function') { | ||
then.call(val, function (val) { res(i, val) }, reject) | ||
return | ||
if (val instanceof Promise && val.then === Promise.prototype.then) { | ||
while (val._32 === 3) { | ||
val = val._8; | ||
} | ||
if (val._32 === 1) return res(i, val._8); | ||
if (val._32 === 2) reject(val._8); | ||
val.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} else { | ||
var then = val.then; | ||
if (typeof then === 'function') { | ||
var p = new Promise(then.bind(val)); | ||
p.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} | ||
} | ||
} | ||
args[i] = val | ||
args[i] = val; | ||
if (--remaining === 0) { | ||
@@ -82,20 +86,20 @@ resolve(args); | ||
for (var i = 0; i < args.length; i++) { | ||
res(i, args[i]) | ||
res(i, args[i]); | ||
} | ||
}) | ||
} | ||
}); | ||
}; | ||
Promise.reject = function (value) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
reject(value); | ||
}); | ||
} | ||
}; | ||
Promise.race = function (values) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
values.forEach(function(value){ | ||
Promise.resolve(value).then(resolve, reject); | ||
}) | ||
}); | ||
}); | ||
} | ||
}; | ||
@@ -106,2 +110,2 @@ /* Prototype Methods */ | ||
return this.then(null, onRejected); | ||
} | ||
}; |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype['finally'] = function (f) { | ||
return this.then(function (value) { | ||
return Promise.resolve(f()).then(function () { | ||
return value | ||
}) | ||
return value; | ||
}); | ||
}, function (err) { | ||
return Promise.resolve(f()).then(function () { | ||
throw err | ||
}) | ||
}) | ||
} | ||
throw err; | ||
}); | ||
}); | ||
}; |
'use strict'; | ||
module.exports = require('./core.js') | ||
require('./done.js') | ||
require('./finally.js') | ||
require('./es6-extensions.js') | ||
require('./node-extensions.js') | ||
module.exports = require('./core.js'); | ||
require('./done.js'); | ||
require('./finally.js'); | ||
require('./es6-extensions.js'); | ||
require('./node-extensions.js'); |
'use strict'; | ||
//This file contains then/promise specific extensions that are only useful for node.js interop | ||
// This file contains then/promise specific extensions that are only useful | ||
// for node.js interop | ||
var Promise = require('./core.js') | ||
var asap = require('asap') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
@@ -13,17 +14,23 @@ /* Static Functions */ | ||
Promise.denodeify = function (fn, argumentCount) { | ||
argumentCount = argumentCount || Infinity | ||
argumentCount = argumentCount || Infinity; | ||
return function () { | ||
var self = this | ||
var args = Array.prototype.slice.call(arguments) | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
return new Promise(function (resolve, reject) { | ||
while (args.length && args.length > argumentCount) { | ||
args.pop() | ||
args.pop(); | ||
} | ||
args.push(function (err, res) { | ||
if (err) reject(err) | ||
else resolve(res) | ||
if (err) reject(err); | ||
else resolve(res); | ||
}) | ||
var res = fn.apply(self, args) | ||
if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') { | ||
resolve(res) | ||
var res = fn.apply(self, args); | ||
if (res && | ||
( | ||
typeof res === 'object' || | ||
typeof res === 'function' | ||
) && | ||
typeof res.then === 'function' | ||
) { | ||
resolve(res); | ||
} | ||
@@ -35,13 +42,16 @@ }) | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null | ||
var ctx = this | ||
var args = Array.prototype.slice.call(arguments); | ||
var callback = | ||
typeof args[args.length - 1] === 'function' ? args.pop() : null; | ||
var ctx = this; | ||
try { | ||
return fn.apply(this, arguments).nodeify(callback, ctx) | ||
return fn.apply(this, arguments).nodeify(callback, ctx); | ||
} catch (ex) { | ||
if (callback === null || typeof callback == 'undefined') { | ||
return new Promise(function (resolve, reject) { reject(ex) }) | ||
return new Promise(function (resolve, reject) { | ||
reject(ex); | ||
}); | ||
} else { | ||
asap(function () { | ||
callback.call(ctx, ex) | ||
callback.call(ctx, ex); | ||
}) | ||
@@ -54,13 +64,13 @@ } | ||
Promise.prototype.nodeify = function (callback, ctx) { | ||
if (typeof callback != 'function') return this | ||
if (typeof callback != 'function') return this; | ||
this.then(function (value) { | ||
asap(function () { | ||
callback.call(ctx, null, value) | ||
}) | ||
callback.call(ctx, null, value); | ||
}); | ||
}, function (err) { | ||
asap(function () { | ||
callback.call(ctx, err) | ||
}) | ||
}) | ||
callback.call(ctx, err); | ||
}); | ||
}); | ||
} |
{ | ||
"name": "promise", | ||
"version": "7.0.0", | ||
"version": "7.0.1", | ||
"description": "Bare bones Promises/A+ implementation", | ||
@@ -15,3 +15,4 @@ "main": "index.js", | ||
"test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999", | ||
"test-memory-leak": "node --expose-gc test/memory-leak.js" | ||
"test-memory-leak": "node --expose-gc test/memory-leak.js", | ||
"coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot" | ||
}, | ||
@@ -27,2 +28,3 @@ "repository": { | ||
"better-assert": "*", | ||
"istanbul": "^0.3.13", | ||
"mocha": "*", | ||
@@ -29,0 +31,0 @@ "promises-aplus-tests": "*", |
@@ -5,3 +5,3 @@ 'use strict'; | ||
function noop() {}; | ||
function noop() {} | ||
@@ -54,96 +54,109 @@ // States: | ||
module.exports = Promise; | ||
function Promise(fn) { | ||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') | ||
if (typeof fn !== 'function') throw new TypeError('not a function') | ||
this._71 = 0; | ||
this._18 = null; | ||
this._61 = []; | ||
if (typeof this !== 'object') { | ||
throw new TypeError('Promises must be constructed via new'); | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new TypeError('not a function'); | ||
} | ||
this._32 = 0; | ||
this._8 = null; | ||
this._89 = []; | ||
if (fn === noop) return; | ||
doResolve(fn, this); | ||
} | ||
Promise.prototype._10 = function (onFulfilled, onRejected) { | ||
var self = this; | ||
return new this.constructor(function (resolve, reject) { | ||
Promise._83 = noop; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) { | ||
return safeThen(this, onFulfilled, onRejected); | ||
} | ||
var res = new Promise(noop); | ||
handle(this, new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
function safeThen(self, onFulfilled, onRejected) { | ||
return new self.constructor(function (resolve, reject) { | ||
var res = new Promise(noop); | ||
res.then(resolve, reject); | ||
self._24(new Handler(onFulfilled, onRejected, res)); | ||
handle(self, new Handler(onFulfilled, onRejected, res)); | ||
}); | ||
}; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) return this._10(onFulfilled, onRejected); | ||
var res = new Promise(noop); | ||
this._24(new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
Promise.prototype._24 = function(deferred) { | ||
if (this._71 === 3) { | ||
this._18._24(deferred); | ||
return; | ||
function handle(self, deferred) { | ||
while (self._32 === 3) { | ||
self = self._8; | ||
} | ||
if (this._71 === 0) { | ||
this._61.push(deferred); | ||
if (self._32 === 0) { | ||
self._89.push(deferred); | ||
return; | ||
} | ||
var state = this._71; | ||
var value = this._18; | ||
setImmediate(function() { | ||
var cb = state === 1 ? deferred.onFulfilled : deferred.onRejected | ||
var cb = self._32 === 1 ? deferred.onFulfilled : deferred.onRejected; | ||
if (cb === null) { | ||
(state === 1 ? deferred.promise._82(value) : deferred.promise._67(value)) | ||
return | ||
if (self._32 === 1) { | ||
resolve(deferred.promise, self._8); | ||
} else { | ||
reject(deferred.promise, self._8); | ||
} | ||
return; | ||
} | ||
var ret = tryCallOne(cb, value); | ||
var ret = tryCallOne(cb, self._8); | ||
if (ret === IS_ERROR) { | ||
deferred.promise._67(LAST_ERROR) | ||
reject(deferred.promise, LAST_ERROR); | ||
} else { | ||
deferred.promise._82(ret) | ||
resolve(deferred.promise, ret); | ||
} | ||
}); | ||
}; | ||
Promise.prototype._82 = function(newValue) { | ||
//Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === this) { | ||
return this._67(new TypeError('A promise cannot be resolved with itself.')) | ||
} | ||
function resolve(self, newValue) { | ||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === self) { | ||
return reject( | ||
self, | ||
new TypeError('A promise cannot be resolved with itself.') | ||
); | ||
} | ||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { | ||
if ( | ||
newValue && | ||
(typeof newValue === 'object' || typeof newValue === 'function') | ||
) { | ||
var then = getThen(newValue); | ||
if (then === IS_ERROR) { | ||
return this._67(LAST_ERROR); | ||
return reject(self, LAST_ERROR); | ||
} | ||
if ( | ||
then === this.then && | ||
newValue instanceof Promise && | ||
newValue._24 === this._24 | ||
then === self.then && | ||
newValue instanceof Promise | ||
) { | ||
this._71 = 3; | ||
this._18 = newValue; | ||
for (var i = 0; i < this._61.length; i++) { | ||
newValue._24(this._61[i]); | ||
} | ||
self._32 = 3; | ||
self._8 = newValue; | ||
finale(self); | ||
return; | ||
} else if (typeof then === 'function') { | ||
doResolve(then.bind(newValue), this) | ||
return | ||
doResolve(then.bind(newValue), self); | ||
return; | ||
} | ||
} | ||
this._71 = 1 | ||
this._18 = newValue | ||
this._94() | ||
self._32 = 1; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._67 = function (newValue) { | ||
this._71 = 2 | ||
this._18 = newValue | ||
this._94() | ||
function reject(self, newValue) { | ||
self._32 = 2; | ||
self._8 = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._94 = function () { | ||
for (var i = 0; i < this._61.length; i++) | ||
this._24(this._61[i]) | ||
this._61 = null | ||
function finale(self) { | ||
for (var i = 0; i < self._89.length; i++) { | ||
handle(self, self._89[i]); | ||
} | ||
self._89 = null; | ||
} | ||
function Handler(onFulfilled, onRejected, promise){ | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null; | ||
this.promise = promise; | ||
@@ -161,14 +174,14 @@ } | ||
var res = tryCallTwo(fn, function (value) { | ||
if (done) return | ||
done = true | ||
promise._82(value) | ||
if (done) return; | ||
done = true; | ||
resolve(promise, value); | ||
}, function (reason) { | ||
if (done) return | ||
done = true | ||
promise._67(reason) | ||
if (done) return; | ||
done = true; | ||
reject(promise, reason); | ||
}) | ||
if (!done && res === IS_ERROR) { | ||
done = true | ||
promise._67(LAST_ERROR) | ||
done = true; | ||
reject(promise, LAST_ERROR); | ||
} | ||
} | ||
} |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype.done = function (onFulfilled, onRejected) { | ||
var self = arguments.length ? this.then.apply(this, arguments) : this | ||
var self = arguments.length ? this.then.apply(this, arguments) : this; | ||
self.then(null, function (err) { | ||
setTimeout(function () { | ||
throw err | ||
}, 0) | ||
}) | ||
} | ||
throw err; | ||
}, 0); | ||
}); | ||
}; |
@@ -5,73 +5,77 @@ 'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
/* Static Functions */ | ||
function ValuePromise(value) { | ||
this.then = function (onFulfilled) { | ||
if (typeof onFulfilled !== 'function') return this | ||
return new Promise(function (resolve, reject) { | ||
setImmediate(function () { | ||
try { | ||
resolve(onFulfilled(value)) | ||
} catch (ex) { | ||
reject(ex); | ||
} | ||
}) | ||
}) | ||
} | ||
var TRUE = valuePromise(true); | ||
var FALSE = valuePromise(false); | ||
var NULL = valuePromise(null); | ||
var UNDEFINED = valuePromise(undefined); | ||
var ZERO = valuePromise(0); | ||
var EMPTYSTRING = valuePromise(''); | ||
function valuePromise(value) { | ||
var p = new Promise(Promise._83); | ||
p._32 = 1; | ||
p._8 = value; | ||
return p; | ||
} | ||
ValuePromise.prototype = Promise.prototype | ||
var TRUE = new ValuePromise(true) | ||
var FALSE = new ValuePromise(false) | ||
var NULL = new ValuePromise(null) | ||
var UNDEFINED = new ValuePromise(undefined) | ||
var ZERO = new ValuePromise(0) | ||
var EMPTYSTRING = new ValuePromise('') | ||
Promise.resolve = function (value) { | ||
if (value instanceof Promise) return value | ||
if (value instanceof Promise) return value; | ||
if (value === null) return NULL | ||
if (value === undefined) return UNDEFINED | ||
if (value === true) return TRUE | ||
if (value === false) return FALSE | ||
if (value === 0) return ZERO | ||
if (value === '') return EMPTYSTRING | ||
if (value === null) return NULL; | ||
if (value === undefined) return UNDEFINED; | ||
if (value === true) return TRUE; | ||
if (value === false) return FALSE; | ||
if (value === 0) return ZERO; | ||
if (value === '') return EMPTYSTRING; | ||
if (typeof value === 'object' || typeof value === 'function') { | ||
try { | ||
var then = value.then | ||
var then = value.then; | ||
if (typeof then === 'function') { | ||
return new Promise(then.bind(value)) | ||
return new Promise(then.bind(value)); | ||
} | ||
} catch (ex) { | ||
return new Promise(function (resolve, reject) { | ||
reject(ex) | ||
}) | ||
reject(ex); | ||
}); | ||
} | ||
} | ||
return valuePromise(value); | ||
}; | ||
return new ValuePromise(value) | ||
} | ||
Promise.all = function (arr) { | ||
var args = Array.prototype.slice.call(arr) | ||
var args = Array.prototype.slice.call(arr); | ||
return new Promise(function (resolve, reject) { | ||
if (args.length === 0) return resolve([]) | ||
var remaining = args.length | ||
if (args.length === 0) return resolve([]); | ||
var remaining = args.length; | ||
function res(i, val) { | ||
if (val && (typeof val === 'object' || typeof val === 'function')) { | ||
var then = val.then | ||
if (typeof then === 'function') { | ||
then.call(val, function (val) { res(i, val) }, reject) | ||
return | ||
if (val instanceof Promise && val.then === Promise.prototype.then) { | ||
while (val._32 === 3) { | ||
val = val._8; | ||
} | ||
if (val._32 === 1) return res(i, val._8); | ||
if (val._32 === 2) reject(val._8); | ||
val.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} else { | ||
var then = val.then; | ||
if (typeof then === 'function') { | ||
var p = new Promise(then.bind(val)); | ||
p.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} | ||
} | ||
} | ||
args[i] = val | ||
args[i] = val; | ||
if (--remaining === 0) { | ||
@@ -82,20 +86,20 @@ resolve(args); | ||
for (var i = 0; i < args.length; i++) { | ||
res(i, args[i]) | ||
res(i, args[i]); | ||
} | ||
}) | ||
} | ||
}); | ||
}; | ||
Promise.reject = function (value) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
reject(value); | ||
}); | ||
} | ||
}; | ||
Promise.race = function (values) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
values.forEach(function(value){ | ||
Promise.resolve(value).then(resolve, reject); | ||
}) | ||
}); | ||
}); | ||
} | ||
}; | ||
@@ -106,2 +110,2 @@ /* Prototype Methods */ | ||
return this.then(null, onRejected); | ||
} | ||
}; |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype['finally'] = function (f) { | ||
return this.then(function (value) { | ||
return Promise.resolve(f()).then(function () { | ||
return value | ||
}) | ||
return value; | ||
}); | ||
}, function (err) { | ||
return Promise.resolve(f()).then(function () { | ||
throw err | ||
}) | ||
}) | ||
} | ||
throw err; | ||
}); | ||
}); | ||
}; |
'use strict'; | ||
module.exports = require('./core.js') | ||
require('./done.js') | ||
require('./finally.js') | ||
require('./es6-extensions.js') | ||
require('./node-extensions.js') | ||
module.exports = require('./core.js'); | ||
require('./done.js'); | ||
require('./finally.js'); | ||
require('./es6-extensions.js'); | ||
require('./node-extensions.js'); |
'use strict'; | ||
//This file contains then/promise specific extensions that are only useful for node.js interop | ||
// This file contains then/promise specific extensions that are only useful | ||
// for node.js interop | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
@@ -13,17 +14,23 @@ /* Static Functions */ | ||
Promise.denodeify = function (fn, argumentCount) { | ||
argumentCount = argumentCount || Infinity | ||
argumentCount = argumentCount || Infinity; | ||
return function () { | ||
var self = this | ||
var args = Array.prototype.slice.call(arguments) | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
return new Promise(function (resolve, reject) { | ||
while (args.length && args.length > argumentCount) { | ||
args.pop() | ||
args.pop(); | ||
} | ||
args.push(function (err, res) { | ||
if (err) reject(err) | ||
else resolve(res) | ||
if (err) reject(err); | ||
else resolve(res); | ||
}) | ||
var res = fn.apply(self, args) | ||
if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') { | ||
resolve(res) | ||
var res = fn.apply(self, args); | ||
if (res && | ||
( | ||
typeof res === 'object' || | ||
typeof res === 'function' | ||
) && | ||
typeof res.then === 'function' | ||
) { | ||
resolve(res); | ||
} | ||
@@ -35,13 +42,16 @@ }) | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null | ||
var ctx = this | ||
var args = Array.prototype.slice.call(arguments); | ||
var callback = | ||
typeof args[args.length - 1] === 'function' ? args.pop() : null; | ||
var ctx = this; | ||
try { | ||
return fn.apply(this, arguments).nodeify(callback, ctx) | ||
return fn.apply(this, arguments).nodeify(callback, ctx); | ||
} catch (ex) { | ||
if (callback === null || typeof callback == 'undefined') { | ||
return new Promise(function (resolve, reject) { reject(ex) }) | ||
return new Promise(function (resolve, reject) { | ||
reject(ex); | ||
}); | ||
} else { | ||
setImmediate(function () { | ||
callback.call(ctx, ex) | ||
callback.call(ctx, ex); | ||
}) | ||
@@ -54,13 +64,13 @@ } | ||
Promise.prototype.nodeify = function (callback, ctx) { | ||
if (typeof callback != 'function') return this | ||
if (typeof callback != 'function') return this; | ||
this.then(function (value) { | ||
setImmediate(function () { | ||
callback.call(ctx, null, value) | ||
}) | ||
callback.call(ctx, null, value); | ||
}); | ||
}, function (err) { | ||
setImmediate(function () { | ||
callback.call(ctx, err) | ||
}) | ||
}) | ||
callback.call(ctx, err); | ||
}); | ||
}); | ||
} |
149
src/core.js
'use strict'; | ||
var asap = require('asap/raw') | ||
var asap = require('asap/raw'); | ||
function noop() {}; | ||
function noop() {} | ||
@@ -53,5 +53,10 @@ // States: | ||
module.exports = Promise; | ||
function Promise(fn) { | ||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') | ||
if (typeof fn !== 'function') throw new TypeError('not a function') | ||
if (typeof this !== 'object') { | ||
throw new TypeError('Promises must be constructed via new'); | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new TypeError('not a function'); | ||
} | ||
this._state = 0; | ||
@@ -63,87 +68,95 @@ this._value = null; | ||
} | ||
Promise.prototype._safeThen = function (onFulfilled, onRejected) { | ||
var self = this; | ||
return new this.constructor(function (resolve, reject) { | ||
Promise._noop = noop; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) { | ||
return safeThen(this, onFulfilled, onRejected); | ||
} | ||
var res = new Promise(noop); | ||
handle(this, new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
function safeThen(self, onFulfilled, onRejected) { | ||
return new self.constructor(function (resolve, reject) { | ||
var res = new Promise(noop); | ||
res.then(resolve, reject); | ||
self._handle(new Handler(onFulfilled, onRejected, res)); | ||
handle(self, new Handler(onFulfilled, onRejected, res)); | ||
}); | ||
}; | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
if (this.constructor !== Promise) return this._safeThen(onFulfilled, onRejected); | ||
var res = new Promise(noop); | ||
this._handle(new Handler(onFulfilled, onRejected, res)); | ||
return res; | ||
}; | ||
Promise.prototype._handle = function(deferred) { | ||
if (this._state === 3) { | ||
this._value._handle(deferred); | ||
return; | ||
function handle(self, deferred) { | ||
while (self._state === 3) { | ||
self = self._value; | ||
} | ||
if (this._state === 0) { | ||
this._deferreds.push(deferred); | ||
if (self._state === 0) { | ||
self._deferreds.push(deferred); | ||
return; | ||
} | ||
var state = this._state; | ||
var value = this._value; | ||
asap(function() { | ||
var cb = state === 1 ? deferred.onFulfilled : deferred.onRejected | ||
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; | ||
if (cb === null) { | ||
(state === 1 ? deferred.promise._resolve(value) : deferred.promise._reject(value)) | ||
return | ||
if (self._state === 1) { | ||
resolve(deferred.promise, self._value); | ||
} else { | ||
reject(deferred.promise, self._value); | ||
} | ||
return; | ||
} | ||
var ret = tryCallOne(cb, value); | ||
var ret = tryCallOne(cb, self._value); | ||
if (ret === IS_ERROR) { | ||
deferred.promise._reject(LAST_ERROR) | ||
reject(deferred.promise, LAST_ERROR); | ||
} else { | ||
deferred.promise._resolve(ret) | ||
resolve(deferred.promise, ret); | ||
} | ||
}); | ||
}; | ||
Promise.prototype._resolve = function(newValue) { | ||
//Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === this) { | ||
return this._reject(new TypeError('A promise cannot be resolved with itself.')) | ||
} | ||
function resolve(self, newValue) { | ||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | ||
if (newValue === self) { | ||
return reject( | ||
self, | ||
new TypeError('A promise cannot be resolved with itself.') | ||
); | ||
} | ||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { | ||
if ( | ||
newValue && | ||
(typeof newValue === 'object' || typeof newValue === 'function') | ||
) { | ||
var then = getThen(newValue); | ||
if (then === IS_ERROR) { | ||
return this._reject(LAST_ERROR); | ||
return reject(self, LAST_ERROR); | ||
} | ||
if ( | ||
then === this.then && | ||
newValue instanceof Promise && | ||
newValue._handle === this._handle | ||
then === self.then && | ||
newValue instanceof Promise | ||
) { | ||
this._state = 3; | ||
this._value = newValue; | ||
for (var i = 0; i < this._deferreds.length; i++) { | ||
newValue._handle(this._deferreds[i]); | ||
} | ||
self._state = 3; | ||
self._value = newValue; | ||
finale(self); | ||
return; | ||
} else if (typeof then === 'function') { | ||
doResolve(then.bind(newValue), this) | ||
return | ||
doResolve(then.bind(newValue), self); | ||
return; | ||
} | ||
} | ||
this._state = 1 | ||
this._value = newValue | ||
this._finale() | ||
self._state = 1; | ||
self._value = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._reject = function (newValue) { | ||
this._state = 2 | ||
this._value = newValue | ||
this._finale() | ||
function reject(self, newValue) { | ||
self._state = 2; | ||
self._value = newValue; | ||
finale(self); | ||
} | ||
Promise.prototype._finale = function () { | ||
for (var i = 0; i < this._deferreds.length; i++) | ||
this._handle(this._deferreds[i]) | ||
this._deferreds = null | ||
function finale(self) { | ||
for (var i = 0; i < self._deferreds.length; i++) { | ||
handle(self, self._deferreds[i]); | ||
} | ||
self._deferreds = null; | ||
} | ||
function Handler(onFulfilled, onRejected, promise){ | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null | ||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; | ||
this.onRejected = typeof onRejected === 'function' ? onRejected : null; | ||
this.promise = promise; | ||
@@ -161,14 +174,14 @@ } | ||
var res = tryCallTwo(fn, function (value) { | ||
if (done) return | ||
done = true | ||
promise._resolve(value) | ||
if (done) return; | ||
done = true; | ||
resolve(promise, value); | ||
}, function (reason) { | ||
if (done) return | ||
done = true | ||
promise._reject(reason) | ||
if (done) return; | ||
done = true; | ||
reject(promise, reason); | ||
}) | ||
if (!done && res === IS_ERROR) { | ||
done = true | ||
promise._reject(LAST_ERROR) | ||
done = true; | ||
reject(promise, LAST_ERROR); | ||
} | ||
} | ||
} |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype.done = function (onFulfilled, onRejected) { | ||
var self = arguments.length ? this.then.apply(this, arguments) : this | ||
var self = arguments.length ? this.then.apply(this, arguments) : this; | ||
self.then(null, function (err) { | ||
setTimeout(function () { | ||
throw err | ||
}, 0) | ||
}) | ||
} | ||
throw err; | ||
}, 0); | ||
}); | ||
}; |
@@ -5,73 +5,77 @@ 'use strict'; | ||
var Promise = require('./core.js') | ||
var asap = require('asap/raw') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap/raw'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
/* Static Functions */ | ||
function ValuePromise(value) { | ||
this.then = function (onFulfilled) { | ||
if (typeof onFulfilled !== 'function') return this | ||
return new Promise(function (resolve, reject) { | ||
asap(function () { | ||
try { | ||
resolve(onFulfilled(value)) | ||
} catch (ex) { | ||
reject(ex); | ||
} | ||
}) | ||
}) | ||
} | ||
var TRUE = valuePromise(true); | ||
var FALSE = valuePromise(false); | ||
var NULL = valuePromise(null); | ||
var UNDEFINED = valuePromise(undefined); | ||
var ZERO = valuePromise(0); | ||
var EMPTYSTRING = valuePromise(''); | ||
function valuePromise(value) { | ||
var p = new Promise(Promise._noop); | ||
p._state = 1; | ||
p._value = value; | ||
return p; | ||
} | ||
ValuePromise.prototype = Promise.prototype | ||
var TRUE = new ValuePromise(true) | ||
var FALSE = new ValuePromise(false) | ||
var NULL = new ValuePromise(null) | ||
var UNDEFINED = new ValuePromise(undefined) | ||
var ZERO = new ValuePromise(0) | ||
var EMPTYSTRING = new ValuePromise('') | ||
Promise.resolve = function (value) { | ||
if (value instanceof Promise) return value | ||
if (value instanceof Promise) return value; | ||
if (value === null) return NULL | ||
if (value === undefined) return UNDEFINED | ||
if (value === true) return TRUE | ||
if (value === false) return FALSE | ||
if (value === 0) return ZERO | ||
if (value === '') return EMPTYSTRING | ||
if (value === null) return NULL; | ||
if (value === undefined) return UNDEFINED; | ||
if (value === true) return TRUE; | ||
if (value === false) return FALSE; | ||
if (value === 0) return ZERO; | ||
if (value === '') return EMPTYSTRING; | ||
if (typeof value === 'object' || typeof value === 'function') { | ||
try { | ||
var then = value.then | ||
var then = value.then; | ||
if (typeof then === 'function') { | ||
return new Promise(then.bind(value)) | ||
return new Promise(then.bind(value)); | ||
} | ||
} catch (ex) { | ||
return new Promise(function (resolve, reject) { | ||
reject(ex) | ||
}) | ||
reject(ex); | ||
}); | ||
} | ||
} | ||
return valuePromise(value); | ||
}; | ||
return new ValuePromise(value) | ||
} | ||
Promise.all = function (arr) { | ||
var args = Array.prototype.slice.call(arr) | ||
var args = Array.prototype.slice.call(arr); | ||
return new Promise(function (resolve, reject) { | ||
if (args.length === 0) return resolve([]) | ||
var remaining = args.length | ||
if (args.length === 0) return resolve([]); | ||
var remaining = args.length; | ||
function res(i, val) { | ||
if (val && (typeof val === 'object' || typeof val === 'function')) { | ||
var then = val.then | ||
if (typeof then === 'function') { | ||
then.call(val, function (val) { res(i, val) }, reject) | ||
return | ||
if (val instanceof Promise && val.then === Promise.prototype.then) { | ||
while (val._state === 3) { | ||
val = val._value; | ||
} | ||
if (val._state === 1) return res(i, val._value); | ||
if (val._state === 2) reject(val._value); | ||
val.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} else { | ||
var then = val.then; | ||
if (typeof then === 'function') { | ||
var p = new Promise(then.bind(val)); | ||
p.then(function (val) { | ||
res(i, val); | ||
}, reject); | ||
return; | ||
} | ||
} | ||
} | ||
args[i] = val | ||
args[i] = val; | ||
if (--remaining === 0) { | ||
@@ -82,20 +86,20 @@ resolve(args); | ||
for (var i = 0; i < args.length; i++) { | ||
res(i, args[i]) | ||
res(i, args[i]); | ||
} | ||
}) | ||
} | ||
}); | ||
}; | ||
Promise.reject = function (value) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
reject(value); | ||
}); | ||
} | ||
}; | ||
Promise.race = function (values) { | ||
return new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
values.forEach(function(value){ | ||
Promise.resolve(value).then(resolve, reject); | ||
}) | ||
}); | ||
}); | ||
} | ||
}; | ||
@@ -106,2 +110,2 @@ /* Prototype Methods */ | ||
return this.then(null, onRejected); | ||
} | ||
}; |
'use strict'; | ||
var Promise = require('./core.js') | ||
var Promise = require('./core.js'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
Promise.prototype['finally'] = function (f) { | ||
return this.then(function (value) { | ||
return Promise.resolve(f()).then(function () { | ||
return value | ||
}) | ||
return value; | ||
}); | ||
}, function (err) { | ||
return Promise.resolve(f()).then(function () { | ||
throw err | ||
}) | ||
}) | ||
} | ||
throw err; | ||
}); | ||
}); | ||
}; |
'use strict'; | ||
module.exports = require('./core.js') | ||
require('./done.js') | ||
require('./finally.js') | ||
require('./es6-extensions.js') | ||
require('./node-extensions.js') | ||
module.exports = require('./core.js'); | ||
require('./done.js'); | ||
require('./finally.js'); | ||
require('./es6-extensions.js'); | ||
require('./node-extensions.js'); |
'use strict'; | ||
//This file contains then/promise specific extensions that are only useful for node.js interop | ||
// This file contains then/promise specific extensions that are only useful | ||
// for node.js interop | ||
var Promise = require('./core.js') | ||
var asap = require('asap') | ||
var Promise = require('./core.js'); | ||
var asap = require('asap'); | ||
module.exports = Promise | ||
module.exports = Promise; | ||
@@ -13,17 +14,23 @@ /* Static Functions */ | ||
Promise.denodeify = function (fn, argumentCount) { | ||
argumentCount = argumentCount || Infinity | ||
argumentCount = argumentCount || Infinity; | ||
return function () { | ||
var self = this | ||
var args = Array.prototype.slice.call(arguments) | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
return new Promise(function (resolve, reject) { | ||
while (args.length && args.length > argumentCount) { | ||
args.pop() | ||
args.pop(); | ||
} | ||
args.push(function (err, res) { | ||
if (err) reject(err) | ||
else resolve(res) | ||
if (err) reject(err); | ||
else resolve(res); | ||
}) | ||
var res = fn.apply(self, args) | ||
if (res && (typeof res === 'object' || typeof res === 'function') && typeof res.then === 'function') { | ||
resolve(res) | ||
var res = fn.apply(self, args); | ||
if (res && | ||
( | ||
typeof res === 'object' || | ||
typeof res === 'function' | ||
) && | ||
typeof res.then === 'function' | ||
) { | ||
resolve(res); | ||
} | ||
@@ -35,13 +42,16 @@ }) | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null | ||
var ctx = this | ||
var args = Array.prototype.slice.call(arguments); | ||
var callback = | ||
typeof args[args.length - 1] === 'function' ? args.pop() : null; | ||
var ctx = this; | ||
try { | ||
return fn.apply(this, arguments).nodeify(callback, ctx) | ||
return fn.apply(this, arguments).nodeify(callback, ctx); | ||
} catch (ex) { | ||
if (callback === null || typeof callback == 'undefined') { | ||
return new Promise(function (resolve, reject) { reject(ex) }) | ||
return new Promise(function (resolve, reject) { | ||
reject(ex); | ||
}); | ||
} else { | ||
asap(function () { | ||
callback.call(ctx, ex) | ||
callback.call(ctx, ex); | ||
}) | ||
@@ -54,13 +64,13 @@ } | ||
Promise.prototype.nodeify = function (callback, ctx) { | ||
if (typeof callback != 'function') return this | ||
if (typeof callback != 'function') return this; | ||
this.then(function (value) { | ||
asap(function () { | ||
callback.call(ctx, null, value) | ||
}) | ||
callback.call(ctx, null, value); | ||
}); | ||
}, function (err) { | ||
asap(function () { | ||
callback.call(ctx, err) | ||
}) | ||
}) | ||
callback.call(ctx, err); | ||
}); | ||
}); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
181573
51
1908
6