Comparing version 3.1.0 to 3.2.0
@@ -14,10 +14,7 @@ /** @license MIT License (c) copyright 2013-2014 original author or authors */ | ||
var when, Promise, promise, slice, _liftAll; | ||
var when = require('./when'); | ||
var Promise = when.Promise; | ||
var _liftAll = require('./lib/liftAll'); | ||
var slice = Array.prototype.slice; | ||
when = require('./when'); | ||
Promise = when.Promise; | ||
_liftAll = require('./lib/liftAll'); | ||
promise = when.promise; | ||
slice = Array.prototype.slice; | ||
return { | ||
@@ -134,7 +131,7 @@ lift: lift, | ||
* @param {Function} f traditional async function to be decorated | ||
* @param {...*} [args] arguments to be prepended for the new function | ||
* @param {...*} [args] arguments to be prepended for the new function @deprecated | ||
* @returns {Function} a promise-returning function | ||
*/ | ||
function lift(f/*, args...*/) { | ||
var args = slice.call(arguments, 1); | ||
var args = arguments.length > 1 ? slice.call(arguments, 1) : []; | ||
return function() { | ||
@@ -207,2 +204,4 @@ return _apply(f, this, args.concat(slice.call(arguments))); | ||
* @returns {function} promisified function that accepts | ||
* | ||
* @deprecated | ||
*/ | ||
@@ -257,6 +256,6 @@ function promisify(asyncFunction, positions) { | ||
return function() { | ||
if(arguments.length <= 1) { | ||
if (arguments.length > 1) { | ||
fn.call(thisArg, slice.call(arguments)); | ||
} else { | ||
fn.apply(thisArg, arguments); | ||
} else { | ||
fn.call(thisArg, slice.call(arguments)); | ||
} | ||
@@ -263,0 +262,0 @@ }; |
@@ -15,3 +15,3 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
var resolve = require('./when').resolve; | ||
var when = require('./when'); | ||
@@ -22,3 +22,3 @@ /** | ||
return function delay(msec, value) { | ||
return resolve(value).delay(msec); | ||
return when(value).delay(msec); | ||
}; | ||
@@ -25,0 +25,0 @@ |
@@ -8,10 +8,10 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
*/ | ||
var PromiseConstructor = module.exports = require('../lib/Promise'); | ||
var unhandledRejections = require('../lib/decorators/unhandledRejection'); | ||
var PromiseConstructor = module.exports = unhandledRejections(require('../lib/Promise')); | ||
var g = typeof global !== 'undefined' && global | ||
|| typeof window !== 'undefined' && window | ||
|| typeof self !== 'undefined' && self; | ||
if(typeof g !== 'undefined' && typeof g.Promise === 'undefined') { | ||
g.Promise = PromiseConstructor; | ||
g['Promise'] = PromiseConstructor; | ||
} |
@@ -9,13 +9,13 @@ !function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Promise=e():"undefined"!=typeof global?global.Promise=e():"undefined"!=typeof self&&(self.Promise=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
*/ | ||
var PromiseConstructor = module.exports = require('../lib/Promise'); | ||
var unhandledRejections = require('../lib/decorators/unhandledRejection'); | ||
var PromiseConstructor = module.exports = unhandledRejections(require('../lib/Promise')); | ||
var g = typeof global !== 'undefined' && global | ||
|| typeof window !== 'undefined' && window | ||
|| typeof self !== 'undefined' && self; | ||
if(typeof g !== 'undefined' && typeof g.Promise === 'undefined') { | ||
g.Promise = PromiseConstructor; | ||
g['Promise'] = PromiseConstructor; | ||
} | ||
},{"../lib/Promise":2}],2:[function(require,module,exports){ | ||
},{"../lib/Promise":2,"../lib/decorators/unhandledRejection":5}],2:[function(require,module,exports){ | ||
/** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
@@ -33,4 +33,3 @@ /** @author Brian Cavalier */ | ||
return makePromise({ | ||
scheduler: new Scheduler(async), | ||
monitor: typeof console !== 'undefined' ? console : void 0 | ||
scheduler: new Scheduler(async) | ||
}); | ||
@@ -41,3 +40,3 @@ | ||
},{"./async":4,"./makePromise":5,"./scheduler":6}],3:[function(require,module,exports){ | ||
},{"./async":4,"./makePromise":6,"./scheduler":7}],3:[function(require,module,exports){ | ||
/** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
@@ -183,2 +182,84 @@ /** @author Brian Cavalier */ | ||
(function(define) { 'use strict'; | ||
define(function(require) { | ||
var timer = require('../timer'); | ||
var logError = (function() { | ||
if(typeof console !== 'undefined') { | ||
if(typeof console.error !== 'undefined') { | ||
return function(e) { | ||
console.error(e); | ||
}; | ||
} | ||
if(typeof console.log !== 'undefined') { | ||
return function(e) { | ||
console.log(e); | ||
}; | ||
} | ||
} | ||
return noop; | ||
}()); | ||
return function unhandledRejection(Promise, enqueue) { | ||
var unhandledRejections = []; | ||
if(typeof enqueue !== 'function') { | ||
enqueue = function(f) { | ||
timer.set(f, 0); | ||
}; | ||
} | ||
function reportUnhandledRejections() { | ||
unhandledRejections.forEach(function (r) { | ||
if(!r.handled) { | ||
logError('Potentially unhandled rejection ' + formatError(r.value)); | ||
} | ||
}); | ||
unhandledRejections = []; | ||
} | ||
Promise.onPotentiallyUnhandledRejection = function(rejection) { | ||
if(unhandledRejections.length === 0) { | ||
enqueue(reportUnhandledRejections); | ||
} | ||
unhandledRejections.push(rejection); | ||
}; | ||
Promise.onFatalRejection = function(rejection) { | ||
enqueue(function() { | ||
throw rejection.value; | ||
}); | ||
}; | ||
return Promise; | ||
}; | ||
function formatError(e) { | ||
var s; | ||
if(typeof e === 'object' && e.stack) { | ||
s = e.stack; | ||
} else { | ||
s = String(e); | ||
if(s === '[object Object]' && typeof JSON !== 'undefined') { | ||
s = JSON.stringify(e); | ||
} | ||
} | ||
return e instanceof Error ? s : s + ' (WARNING: non-Error used)'; | ||
} | ||
function noop() {} | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); | ||
},{"../timer":8}],6:[function(require,module,exports){ | ||
/** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
/** @author Brian Cavalier */ | ||
/** @author John Hann */ | ||
(function(define) { 'use strict'; | ||
define(function() { | ||
@@ -289,3 +370,3 @@ | ||
* @private | ||
* @returns {{_handler: DeferredHandler, promise: Promise}} | ||
* @returns {Promise} | ||
*/ | ||
@@ -318,14 +399,27 @@ function defer() { | ||
* this promise's fulfillment. | ||
* @param [onFulfilled] {Function} fulfillment handler | ||
* @param [onRejected] {Function} rejection handler | ||
* @param [onProgress] {Function} progress handler | ||
* @param {function=} onFulfilled fulfillment handler | ||
* @param {function=} onRejected rejection handler | ||
* @deprecated @param {function=} onProgress progress handler | ||
* @return {Promise} new promise | ||
*/ | ||
Promise.prototype.then = function(onFulfilled, onRejected, onProgress) { | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
var parent = this._handler; | ||
if (typeof onFulfilled !== 'function' && parent.join().state > 0) { | ||
// Short circuit: value will not change, simply share handler | ||
return promiseFromHandler(parent); | ||
} | ||
var p = this._beget(); | ||
var parent = this._handler; | ||
var child = p._handler; | ||
parent.when(child.resolve, child.notify, child, | ||
parent.receiver, onFulfilled, onRejected, onProgress); | ||
parent.when({ | ||
resolve: child.resolve, | ||
notify: child.notify, | ||
context: child, | ||
receiver: parent.receiver, | ||
fulfilled: onFulfilled, | ||
rejected: onRejected, | ||
progress: arguments.length > 2 ? arguments[2] : void 0 | ||
}); | ||
@@ -368,2 +462,19 @@ return p; | ||
/** | ||
* Check if x is a rejected promise, and if so, delegate to handler._fatal | ||
* @private | ||
* @param {*} x | ||
*/ | ||
Promise.prototype._maybeFatal = function(x) { | ||
if(!maybeThenable(x)) { | ||
return; | ||
} | ||
var handler = getHandlerUnchecked(x); | ||
handler.context = this._handler.context; | ||
handler.chain(handler, void 0, function() { | ||
this._fatal(this.context); | ||
}); | ||
}; | ||
// Array combinators | ||
@@ -382,3 +493,3 @@ | ||
function all(promises) { | ||
/*jshint maxcomplexity:6*/ | ||
/*jshint maxcomplexity:8*/ | ||
var resolver = new DeferredHandler(); | ||
@@ -388,10 +499,20 @@ var len = promises.length >>> 0; | ||
var results = []; | ||
var i, h; | ||
var i, h, x; | ||
for (i = 0; i < len; ++i) { | ||
if (i in promises) { | ||
h = getHandlerUnchecked(promises[i]); | ||
if(h.state === 0) { | ||
x = promises[i]; | ||
if (x === void 0 && !(i in promises)) { | ||
--pending; | ||
continue; | ||
} | ||
if (maybeThenable(x)) { | ||
h = x instanceof Promise | ||
? x._handler.join() | ||
: getHandlerUntrusted(x); | ||
if (h.state === 0) { | ||
resolveOne(resolver, results, h, i); | ||
} else if (h.state === 1) { | ||
} else if (h.state > 0) { | ||
results[i] = h.value; | ||
@@ -403,3 +524,5 @@ --pending; | ||
} | ||
} else { | ||
results[i] = x; | ||
--pending; | ||
@@ -447,6 +570,9 @@ } | ||
var h = new DeferredHandler(); | ||
for(var i=0; i<promises.length; ++i) { | ||
getHandler(promises[i]).chain(h, h.resolve, h.reject); | ||
var i, x; | ||
for(i=0; i<promises.length; ++i) { | ||
x = promises[i]; | ||
if (x !== void 0 && i in promises) { | ||
getHandler(x).chain(h, h.resolve, h.reject); | ||
} | ||
} | ||
return promiseFromHandler(h); | ||
@@ -467,3 +593,4 @@ } | ||
if(x instanceof Promise) { | ||
return getHandlerChecked(x, h); | ||
var xh = x._handler.join(); | ||
return h === xh ? promiseCycleHandler() : xh; | ||
} | ||
@@ -487,13 +614,2 @@ return maybeThenable(x) ? getHandlerUntrusted(x) : new FulfilledHandler(x); | ||
/** | ||
* Get x's handler, checking for cycles | ||
* @param {Promise} x | ||
* @param {object?} h handler to check for cycles | ||
* @returns {object} handler | ||
*/ | ||
function getHandlerChecked(x, h) { | ||
var xh = x._handler.join(); | ||
return h === xh ? promiseCycleHandler() : xh; | ||
} | ||
/** | ||
* Get a handler for potentially untrusted thenable x | ||
@@ -515,2 +631,15 @@ * @param {*} x | ||
/** | ||
* Recursively collapse handler chain to find the handler | ||
* nearest to the fully resolved value. | ||
* @param {Handler} h | ||
* @returns {*} | ||
*/ | ||
function join(h) { | ||
while(h.handler !== void 0) { | ||
h = h.handler; | ||
} | ||
return h; | ||
} | ||
/** | ||
* Handler for a promise that is pending forever | ||
@@ -535,27 +664,24 @@ * @private | ||
Handler.prototype.join = function() { return this; }; | ||
Handler.prototype.join = function() { return join(this); }; | ||
Handler.prototype.chain = function(to, f, r, u) { | ||
this.when(noop, noop, void 0, to, f, r, u); | ||
Handler.prototype.chain = function(to, fulfilled, rejected, progress) { | ||
this.when({ | ||
resolve: noop, | ||
notify: noop, | ||
context: void 0, | ||
receiver: to, | ||
fulfilled: fulfilled, | ||
rejected: rejected, | ||
progress: progress | ||
}); | ||
}; | ||
Handler.prototype._env = environment.monitor || Promise; | ||
Handler.prototype._isMonitored = function() { | ||
return typeof this._env.promiseMonitor !== 'undefined'; | ||
Handler.prototype.fold = function(to, f, z) { | ||
join(this).chain(to, function(x) { | ||
getHandler(z).chain(this, function(z) { | ||
this.resolve(tryCatchReject2(f, z, x, this.receiver)); | ||
}, this.reject, this.notify); | ||
}, to.reject, to.notify); | ||
}; | ||
Handler.prototype._createContext = function(fromContext) { | ||
var parent = fromContext || executionContext[executionContext.length - 1]; | ||
this.context = { stack: void 0, parent: parent }; | ||
this._env.promiseMonitor.captureStack(this.context, this.constructor); | ||
}; | ||
Handler.prototype._enterContext = function() { | ||
executionContext.push(this.context); | ||
}; | ||
Handler.prototype._exitContext = function() { | ||
executionContext.pop(); | ||
}; | ||
/** | ||
@@ -567,2 +693,4 @@ * Handler that manages a queue of consumers waiting on a pending promise | ||
function DeferredHandler(receiver, inheritedContext) { | ||
Promise.createContext(this, inheritedContext); | ||
this.consumers = []; | ||
@@ -573,5 +701,2 @@ this.receiver = receiver; | ||
this.state = 0; | ||
if(this._isMonitored()) { | ||
this._createContext(inheritedContext); | ||
} | ||
} | ||
@@ -586,7 +711,11 @@ | ||
DeferredHandler.prototype.resolve = function(x) { | ||
this._join(getHandler(x, this)); | ||
if(!this.resolved) { | ||
this._resolve(getHandler(x, this)); | ||
} | ||
}; | ||
DeferredHandler.prototype.reject = function(x) { | ||
this._join(new RejectedHandler(x)); | ||
if(!this.resolved) { | ||
this._resolve(new RejectedHandler(x)); | ||
} | ||
}; | ||
@@ -596,4 +725,3 @@ | ||
if (this.resolved) { | ||
this.handler = this.handler.join(); | ||
return this.handler; | ||
return this.handler = join(this.handler); | ||
} else { | ||
@@ -606,15 +734,11 @@ return this; | ||
var q = this.consumers; | ||
var handler = this.handler = this.handler.join(); | ||
var handler = this.handler.join(); | ||
this.consumers = void 0; | ||
for (var i = 0; i < q.length; i+=7) { | ||
handler.when(q[i], q[i+1], q[i+2], q[i+3], q[i+4], q[i+5], q[i+6]); | ||
for (var i = 0; i < q.length; ++i) { | ||
handler.when(q[i]); | ||
} | ||
}; | ||
DeferredHandler.prototype._join = function(handler) { | ||
if(this.resolved) { | ||
return; | ||
} | ||
DeferredHandler.prototype._resolve = function(handler) { | ||
this.resolved = true; | ||
@@ -624,15 +748,12 @@ this.handler = handler; | ||
if(this._isMonitored()) { | ||
if(this.context !== void 0) { | ||
handler._reportTrace(this.context); | ||
this.context = void 0; | ||
} | ||
}; | ||
DeferredHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
if(this._isMonitored()) { this.context = void 0; } | ||
DeferredHandler.prototype.when = function(continuation) { | ||
if(this.resolved) { | ||
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.handler)); | ||
tasks.enqueue(new ContinuationTask(continuation, this.handler)); | ||
} else { | ||
this.consumers.push(resolve, notify, t, receiver, f, r, u); | ||
this.consumers.push(continuation); | ||
} | ||
@@ -655,2 +776,7 @@ }; | ||
DeferredHandler.prototype._fatal = function(context) { | ||
var c = typeof context === 'undefined' ? this.context : context; | ||
this.resolved && this.handler.join()._fatal(c); | ||
}; | ||
/** | ||
@@ -669,6 +795,2 @@ * Abstract base for handler that delegates to another handler | ||
DelegateHandler.prototype.join = function() { | ||
return this.handler.join(); | ||
}; | ||
DelegateHandler.prototype.inspect = function() { | ||
@@ -698,4 +820,4 @@ return this.join().inspect(); | ||
AsyncHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.join())); | ||
AsyncHandler.prototype.when = function(continuation) { | ||
tasks.enqueue(new ContinuationTask(continuation, this.join())); | ||
}; | ||
@@ -717,3 +839,3 @@ | ||
BoundHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
BoundHandler.prototype.when = function(continuation) { | ||
// Because handlers are allowed to be shared among promises, | ||
@@ -724,5 +846,5 @@ // each of which possibly having a different receiver, we have | ||
if(this.receiver !== void 0) { | ||
receiver = this.receiver; | ||
continuation.receiver = this.receiver; | ||
} | ||
this.join().when(resolve, notify, t, receiver, f, r, u); | ||
this.join().when(continuation); | ||
}; | ||
@@ -746,13 +868,12 @@ | ||
ThenableHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
ThenableHandler.prototype.when = function(continuation) { | ||
if(!this.assimilated) { | ||
this.assimilated = true; | ||
this._assimilate(); | ||
assimilate(this); | ||
} | ||
DeferredHandler.prototype.when.call(this, resolve, notify, t, receiver, f, r, u); | ||
DeferredHandler.prototype.when.call(this, continuation); | ||
}; | ||
ThenableHandler.prototype._assimilate = function() { | ||
var h = this; | ||
this._try(this.untrustedThen, this.thenable, _resolve, _reject, _notify); | ||
function assimilate(h) { | ||
tryAssimilate(h.untrustedThen, h.thenable, _resolve, _reject, _notify); | ||
@@ -762,5 +883,5 @@ function _resolve(x) { h.resolve(x); } | ||
function _notify(x) { h.notify(x); } | ||
}; | ||
} | ||
ThenableHandler.prototype._try = function(then, thenable, resolve, reject, notify) { | ||
function tryAssimilate(then, thenable, resolve, reject, notify) { | ||
try { | ||
@@ -771,3 +892,3 @@ then.call(thenable, resolve, reject, notify); | ||
} | ||
}; | ||
} | ||
@@ -781,8 +902,6 @@ /** | ||
function FulfilledHandler(x) { | ||
Promise.createContext(this); | ||
this.value = x; | ||
this.state = 1; | ||
if(this._isMonitored()) { | ||
this._createContext(); | ||
} | ||
} | ||
@@ -796,12 +915,14 @@ | ||
FulfilledHandler.prototype.when = function(resolve, notify, t, receiver, f) { | ||
if(this._isMonitored()) { this._enterContext(); } | ||
FulfilledHandler.prototype.when = function(cont) { | ||
var x; | ||
var x = typeof f === 'function' | ||
? tryCatchReject(f, this.value, receiver) | ||
: this.value; | ||
if (typeof cont.fulfilled === 'function') { | ||
Promise.enterContext(this); | ||
x = tryCatchReject(cont.fulfilled, this.value, cont.receiver); | ||
Promise.exitContext(); | ||
} else { | ||
x = this.value; | ||
} | ||
if(this._isMonitored()) { this._exitContext(); } | ||
resolve.call(t, x); | ||
cont.resolve.call(cont.context, x); | ||
}; | ||
@@ -816,10 +937,9 @@ | ||
function RejectedHandler(x) { | ||
Promise.createContext(this); | ||
this.value = x; | ||
this.state = -1; | ||
this.handled = false; | ||
if(this._isMonitored()) { | ||
this.id = errorId++; | ||
this._createContext(); | ||
this._reportTrace(); | ||
} | ||
this._reportTrace(); | ||
} | ||
@@ -833,33 +953,42 @@ | ||
RejectedHandler.prototype.when = function(resolve, notify, t, receiver, f, r) { | ||
if(this._isMonitored()) { | ||
RejectedHandler.prototype.when = function(cont) { | ||
var x; | ||
if (typeof cont.rejected === 'function') { | ||
this._removeTrace(); | ||
this._enterContext(); | ||
Promise.enterContext(this); | ||
x = tryCatchReject(cont.rejected, this.value, cont.receiver); | ||
Promise.exitContext(); | ||
} else { | ||
x = promiseFromHandler(this); | ||
} | ||
var x = typeof r === 'function' | ||
? tryCatchReject(r, this.value, receiver) | ||
: promiseFromHandler(this); | ||
if(this._isMonitored()) { this._exitContext(); } | ||
resolve.call(t, x); | ||
cont.resolve.call(cont.context, x); | ||
}; | ||
RejectedHandler.prototype._reportTrace = function(context) { | ||
this._env.promiseMonitor.addTrace(this, context); | ||
Promise.onPotentiallyUnhandledRejection(this, context); | ||
}; | ||
RejectedHandler.prototype._removeTrace = function() { | ||
this._env.promiseMonitor.removeTrace(this); | ||
this.handled = true; | ||
Promise.onPotentiallyUnhandledRejectionHandled(this); | ||
}; | ||
RejectedHandler.prototype._fatal = function() { | ||
this._env.promiseMonitor.fatal(this); | ||
RejectedHandler.prototype._fatal = function(context) { | ||
Promise.onFatalRejection(this, context); | ||
}; | ||
// Execution context tracking for long stack traces | ||
// Unhandled rejection hooks | ||
// By default, everything is a noop | ||
var executionContext = []; | ||
var errorId = 0; | ||
// TODO: Better names: "annotate"? | ||
Promise.createContext | ||
= Promise.enterContext | ||
= Promise.exitContext | ||
= Promise.onPotentiallyUnhandledRejection | ||
= Promise.onPotentiallyUnhandledRejectionHandled | ||
= Promise.onFatalRejection | ||
= noop; | ||
@@ -893,9 +1022,9 @@ // Errors and singletons | ||
*/ | ||
function RunHandlerTask(a, b, c, d, e, f, g, handler) { | ||
this.a=a;this.b=b;this.c=c;this.d=d;this.e=e;this.f=f;this.g=g; | ||
function ContinuationTask(continuation, handler) { | ||
this.continuation = continuation; | ||
this.handler = handler; | ||
} | ||
RunHandlerTask.prototype.run = function() { | ||
this.handler.join().when(this.a,this.b,this.c,this.d,this.e,this.f,this.g); | ||
ContinuationTask.prototype.run = function() { | ||
this.handler.join().when(this.continuation); | ||
}; | ||
@@ -916,13 +1045,13 @@ | ||
// First progress handler is at index 1 | ||
for (var i = 1; i < q.length; i+=7) { | ||
this._notify(q[i], q[i+1], q[i+2], q[i+5]); | ||
for (var i = 0; i < q.length; ++i) { | ||
this._notify(q[i]); | ||
} | ||
}; | ||
ProgressTask.prototype._notify = function(notify, t, receiver, u) { | ||
var x = typeof u === 'function' | ||
? tryCatchReturn(u, this.value, receiver) | ||
ProgressTask.prototype._notify = function(continuation) { | ||
var x = typeof continuation.progress === 'function' | ||
? tryCatchReturn(continuation.progress, this.value, continuation.receiver) | ||
: this.value; | ||
notify.call(t, x); | ||
continuation.notify.call(continuation.context, x); | ||
}; | ||
@@ -954,2 +1083,14 @@ | ||
/** | ||
* Same as above, but includes the extra argument parameter. | ||
* @private | ||
*/ | ||
function tryCatchReject2(f, x, y, thisArg) { | ||
try { | ||
return f.call(thisArg, x, y); | ||
} catch(e) { | ||
return reject(e); | ||
} | ||
} | ||
/** | ||
* Return f.call(thisArg, x), or if it throws, *return* the exception | ||
@@ -978,3 +1119,3 @@ * @private | ||
},{}],6:[function(require,module,exports){ | ||
},{}],7:[function(require,module,exports){ | ||
/** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
@@ -1008,5 +1149,6 @@ /** @author Brian Cavalier */ | ||
Scheduler.prototype.enqueue = function(task) { | ||
if(this._handlerQueue.push(task) === 1) { | ||
if(this._handlerQueue.length === 0) { | ||
this._enqueue(this.drainQueue); | ||
} | ||
this._handlerQueue.push(task); | ||
}; | ||
@@ -1031,5 +1173,34 @@ | ||
},{"./Queue":3}]},{},[1]) | ||
},{"./Queue":3}],8:[function(require,module,exports){ | ||
/** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
/** @author Brian Cavalier */ | ||
/** @author John Hann */ | ||
(function(define) { 'use strict'; | ||
define(function(require) { | ||
/*global setTimeout,clearTimeout*/ | ||
var cjsRequire, vertx, setTimer, clearTimer; | ||
cjsRequire = require; | ||
try { | ||
vertx = cjsRequire('vertx'); | ||
setTimer = function (f, ms) { return vertx.setTimer(ms, f); }; | ||
clearTimer = vertx.cancelTimer; | ||
} catch (e) { | ||
setTimer = function(f, ms) { return setTimeout(f, ms); }; | ||
clearTimer = function(t) { return clearTimeout(t); }; | ||
} | ||
return { | ||
set: setTimer, | ||
clear: clearTimer | ||
}; | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); | ||
},{}]},{},[1]) | ||
(1) | ||
}); | ||
; |
@@ -14,9 +14,7 @@ /** @license MIT License (c) copyright 2013-2014 original author or authors */ | ||
var when, slice, attempt, _liftAll; | ||
var when = require('./when'); | ||
var attempt = when['try']; | ||
var _liftAll = require('./lib/liftAll'); | ||
var slice = Array.prototype.slice; | ||
when = require('./when'); | ||
attempt = when['try']; | ||
_liftAll = require('./lib/liftAll'); | ||
slice = Array.prototype.slice; | ||
return { | ||
@@ -51,7 +49,7 @@ lift: lift, | ||
* @param {Function} f function to be bound | ||
* @param {...*} [args] arguments to be prepended for the new function | ||
* @param {...*} [args] arguments to be prepended for the new function @deprecated | ||
* @returns {Function} a promise-returning function | ||
*/ | ||
function lift(f /*, args... */) { | ||
var args = slice.call(arguments, 1); | ||
var args = arguments.length > 1 ? slice.call(arguments, 1) : []; | ||
return function() { | ||
@@ -104,8 +102,6 @@ return _apply(f, this, args.concat(slice.call(arguments))); | ||
return function() { | ||
var thisArg, args, firstPromise; | ||
var thisArg = this; | ||
var args = slice.call(arguments); | ||
var firstPromise = attempt.apply(thisArg, [f].concat(args)); | ||
thisArg = this; | ||
args = slice.call(arguments); | ||
firstPromise = attempt.apply(thisArg, [f].concat(args)); | ||
return when.reduce(funcs, function(arg, func) { | ||
@@ -112,0 +108,0 @@ return func.call(thisArg, arg); |
@@ -14,7 +14,5 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
var when, slice; | ||
var when = require('./when'); | ||
var slice = Array.prototype.slice; | ||
when = require('./when'); | ||
slice = Array.prototype.slice; | ||
return { | ||
@@ -21,0 +19,0 @@ apply: apply, |
@@ -82,2 +82,4 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
* @returns {Promise} promise for the earliest n fulfillment values | ||
* | ||
* @deprecated | ||
*/ | ||
@@ -84,0 +86,0 @@ function some(promises, n) { |
@@ -6,11 +6,9 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
(function(define) { 'use strict'; | ||
define(function(require) { | ||
define(function() { | ||
var setTimer = require('../timer').set; | ||
return function flow(Promise) { | ||
var resolve = Promise.resolve; | ||
var reject = Promise.reject; | ||
var origCatch = Promise.prototype['catch']; | ||
var nil = Promise.nil; | ||
@@ -28,30 +26,8 @@ /** | ||
var h = this._handler; | ||
h.when(this._maybeFatal, noop, this, h.receiver, onResult, onError); | ||
h.when({ resolve: this._maybeFatal, notify: noop, context: this, | ||
receiver: h.receiver, arg: nil, fulfilled: onResult, rejected: onError, | ||
progress: void 0 }); | ||
}; | ||
/** | ||
* Check if x is a rejected promise, and if so, delegate to this._fatal | ||
* @private | ||
* @param {*} x | ||
*/ | ||
Promise.prototype._maybeFatal = function(x) { | ||
if((typeof x === 'object' || typeof x === 'function') && x !== null) { | ||
// Delegate to promise._fatal in case it has been overridden | ||
resolve(x)._handler.chain(this, void 0, this._fatal); | ||
} | ||
}; | ||
/** | ||
* Propagate fatal errors to the host environment. | ||
* @private | ||
*/ | ||
Promise.prototype._fatal = function(e) { | ||
if(this._handler._isMonitored()) { | ||
this._handler.join()._fatal(e); | ||
} else { | ||
setTimer(function() { throw e; }, 0); | ||
} | ||
}; | ||
/** | ||
* Add Error-type and predicate matching to catch. Examples: | ||
@@ -176,2 +152,2 @@ * promise.catch(TypeError, handleTypeError) | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); |
@@ -29,13 +29,5 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
function iterate(f, condition, handler, x) { | ||
return resolve(x).then(function(x) { | ||
return resolve(condition(x)).then(function(done) { | ||
return done ? x : next(x); | ||
}); | ||
}); | ||
function next(nextValue) { | ||
return resolve(handler(nextValue)).then(function() { | ||
return iterate(f, condition, handler, f(nextValue)); | ||
}); | ||
} | ||
return unfold(function(x) { | ||
return [x, f(x)]; | ||
}, condition, handler, x); | ||
} | ||
@@ -42,0 +34,0 @@ |
@@ -9,2 +9,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
var timer = require('../timer'); | ||
var TimeoutError = require('../TimeoutError'); | ||
@@ -20,9 +21,7 @@ return function timed(Promise) { | ||
var p = this._beget(); | ||
var h = p._handler; | ||
this._handler.chain(p._handler, | ||
function delay(x) { | ||
var h = this; // this = p._handler | ||
this._handler.chain(h, function delay(x) { | ||
timer.set(function() { h.resolve(x); }, ms); | ||
}, | ||
p._handler.reject, p._handler.notify); | ||
}, h.reject, h.notify); | ||
@@ -44,6 +43,7 @@ return p; | ||
var p = this._beget(); | ||
var h = p._handler; | ||
var t = timer.set(onTimeout, ms); | ||
this._handler.chain(p._handler, | ||
this._handler.chain(h, | ||
function onFulfill(x) { | ||
@@ -57,3 +57,3 @@ timer.clear(t); | ||
}, | ||
p._handler.notify); | ||
h.notify); | ||
@@ -63,4 +63,4 @@ return p; | ||
function onTimeout() { | ||
p._handler.reject(hasReason | ||
? reason : new Error('timed out after ' + ms + 'ms')); | ||
h.reject(hasReason | ||
? reason : new TimeoutError('timed out after ' + ms + 'ms')); | ||
} | ||
@@ -70,3 +70,2 @@ }; | ||
return Promise; | ||
}; | ||
@@ -73,0 +72,0 @@ |
@@ -111,3 +111,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
* @private | ||
* @returns {{_handler: DeferredHandler, promise: Promise}} | ||
* @returns {Promise} | ||
*/ | ||
@@ -140,14 +140,27 @@ function defer() { | ||
* this promise's fulfillment. | ||
* @param [onFulfilled] {Function} fulfillment handler | ||
* @param [onRejected] {Function} rejection handler | ||
* @param [onProgress] {Function} progress handler | ||
* @param {function=} onFulfilled fulfillment handler | ||
* @param {function=} onRejected rejection handler | ||
* @deprecated @param {function=} onProgress progress handler | ||
* @return {Promise} new promise | ||
*/ | ||
Promise.prototype.then = function(onFulfilled, onRejected, onProgress) { | ||
Promise.prototype.then = function(onFulfilled, onRejected) { | ||
var parent = this._handler; | ||
if (typeof onFulfilled !== 'function' && parent.join().state > 0) { | ||
// Short circuit: value will not change, simply share handler | ||
return promiseFromHandler(parent); | ||
} | ||
var p = this._beget(); | ||
var parent = this._handler; | ||
var child = p._handler; | ||
parent.when(child.resolve, child.notify, child, | ||
parent.receiver, onFulfilled, onRejected, onProgress); | ||
parent.when({ | ||
resolve: child.resolve, | ||
notify: child.notify, | ||
context: child, | ||
receiver: parent.receiver, | ||
fulfilled: onFulfilled, | ||
rejected: onRejected, | ||
progress: arguments.length > 2 ? arguments[2] : void 0 | ||
}); | ||
@@ -190,2 +203,19 @@ return p; | ||
/** | ||
* Check if x is a rejected promise, and if so, delegate to handler._fatal | ||
* @private | ||
* @param {*} x | ||
*/ | ||
Promise.prototype._maybeFatal = function(x) { | ||
if(!maybeThenable(x)) { | ||
return; | ||
} | ||
var handler = getHandlerUnchecked(x); | ||
handler.context = this._handler.context; | ||
handler.chain(handler, void 0, function() { | ||
this._fatal(this.context); | ||
}); | ||
}; | ||
// Array combinators | ||
@@ -204,3 +234,3 @@ | ||
function all(promises) { | ||
/*jshint maxcomplexity:6*/ | ||
/*jshint maxcomplexity:8*/ | ||
var resolver = new DeferredHandler(); | ||
@@ -210,10 +240,20 @@ var len = promises.length >>> 0; | ||
var results = []; | ||
var i, h; | ||
var i, h, x; | ||
for (i = 0; i < len; ++i) { | ||
if (i in promises) { | ||
h = getHandlerUnchecked(promises[i]); | ||
if(h.state === 0) { | ||
x = promises[i]; | ||
if (x === void 0 && !(i in promises)) { | ||
--pending; | ||
continue; | ||
} | ||
if (maybeThenable(x)) { | ||
h = x instanceof Promise | ||
? x._handler.join() | ||
: getHandlerUntrusted(x); | ||
if (h.state === 0) { | ||
resolveOne(resolver, results, h, i); | ||
} else if (h.state === 1) { | ||
} else if (h.state > 0) { | ||
results[i] = h.value; | ||
@@ -225,3 +265,5 @@ --pending; | ||
} | ||
} else { | ||
results[i] = x; | ||
--pending; | ||
@@ -269,6 +311,9 @@ } | ||
var h = new DeferredHandler(); | ||
for(var i=0; i<promises.length; ++i) { | ||
getHandler(promises[i]).chain(h, h.resolve, h.reject); | ||
var i, x; | ||
for(i=0; i<promises.length; ++i) { | ||
x = promises[i]; | ||
if (x !== void 0 && i in promises) { | ||
getHandler(x).chain(h, h.resolve, h.reject); | ||
} | ||
} | ||
return promiseFromHandler(h); | ||
@@ -289,3 +334,4 @@ } | ||
if(x instanceof Promise) { | ||
return getHandlerChecked(x, h); | ||
var xh = x._handler.join(); | ||
return h === xh ? promiseCycleHandler() : xh; | ||
} | ||
@@ -309,13 +355,2 @@ return maybeThenable(x) ? getHandlerUntrusted(x) : new FulfilledHandler(x); | ||
/** | ||
* Get x's handler, checking for cycles | ||
* @param {Promise} x | ||
* @param {object?} h handler to check for cycles | ||
* @returns {object} handler | ||
*/ | ||
function getHandlerChecked(x, h) { | ||
var xh = x._handler.join(); | ||
return h === xh ? promiseCycleHandler() : xh; | ||
} | ||
/** | ||
* Get a handler for potentially untrusted thenable x | ||
@@ -337,2 +372,15 @@ * @param {*} x | ||
/** | ||
* Recursively collapse handler chain to find the handler | ||
* nearest to the fully resolved value. | ||
* @param {Handler} h | ||
* @returns {*} | ||
*/ | ||
function join(h) { | ||
while(h.handler !== void 0) { | ||
h = h.handler; | ||
} | ||
return h; | ||
} | ||
/** | ||
* Handler for a promise that is pending forever | ||
@@ -357,27 +405,24 @@ * @private | ||
Handler.prototype.join = function() { return this; }; | ||
Handler.prototype.join = function() { return join(this); }; | ||
Handler.prototype.chain = function(to, f, r, u) { | ||
this.when(noop, noop, void 0, to, f, r, u); | ||
Handler.prototype.chain = function(to, fulfilled, rejected, progress) { | ||
this.when({ | ||
resolve: noop, | ||
notify: noop, | ||
context: void 0, | ||
receiver: to, | ||
fulfilled: fulfilled, | ||
rejected: rejected, | ||
progress: progress | ||
}); | ||
}; | ||
Handler.prototype._env = environment.monitor || Promise; | ||
Handler.prototype._isMonitored = function() { | ||
return typeof this._env.promiseMonitor !== 'undefined'; | ||
Handler.prototype.fold = function(to, f, z) { | ||
join(this).chain(to, function(x) { | ||
getHandler(z).chain(this, function(z) { | ||
this.resolve(tryCatchReject2(f, z, x, this.receiver)); | ||
}, this.reject, this.notify); | ||
}, to.reject, to.notify); | ||
}; | ||
Handler.prototype._createContext = function(fromContext) { | ||
var parent = fromContext || executionContext[executionContext.length - 1]; | ||
this.context = { stack: void 0, parent: parent }; | ||
this._env.promiseMonitor.captureStack(this.context, this.constructor); | ||
}; | ||
Handler.prototype._enterContext = function() { | ||
executionContext.push(this.context); | ||
}; | ||
Handler.prototype._exitContext = function() { | ||
executionContext.pop(); | ||
}; | ||
/** | ||
@@ -389,2 +434,4 @@ * Handler that manages a queue of consumers waiting on a pending promise | ||
function DeferredHandler(receiver, inheritedContext) { | ||
Promise.createContext(this, inheritedContext); | ||
this.consumers = []; | ||
@@ -395,5 +442,2 @@ this.receiver = receiver; | ||
this.state = 0; | ||
if(this._isMonitored()) { | ||
this._createContext(inheritedContext); | ||
} | ||
} | ||
@@ -408,7 +452,11 @@ | ||
DeferredHandler.prototype.resolve = function(x) { | ||
this._join(getHandler(x, this)); | ||
if(!this.resolved) { | ||
this._resolve(getHandler(x, this)); | ||
} | ||
}; | ||
DeferredHandler.prototype.reject = function(x) { | ||
this._join(new RejectedHandler(x)); | ||
if(!this.resolved) { | ||
this._resolve(new RejectedHandler(x)); | ||
} | ||
}; | ||
@@ -418,4 +466,3 @@ | ||
if (this.resolved) { | ||
this.handler = this.handler.join(); | ||
return this.handler; | ||
return this.handler = join(this.handler); | ||
} else { | ||
@@ -428,15 +475,11 @@ return this; | ||
var q = this.consumers; | ||
var handler = this.handler = this.handler.join(); | ||
var handler = this.handler.join(); | ||
this.consumers = void 0; | ||
for (var i = 0; i < q.length; i+=7) { | ||
handler.when(q[i], q[i+1], q[i+2], q[i+3], q[i+4], q[i+5], q[i+6]); | ||
for (var i = 0; i < q.length; ++i) { | ||
handler.when(q[i]); | ||
} | ||
}; | ||
DeferredHandler.prototype._join = function(handler) { | ||
if(this.resolved) { | ||
return; | ||
} | ||
DeferredHandler.prototype._resolve = function(handler) { | ||
this.resolved = true; | ||
@@ -446,15 +489,12 @@ this.handler = handler; | ||
if(this._isMonitored()) { | ||
if(this.context !== void 0) { | ||
handler._reportTrace(this.context); | ||
this.context = void 0; | ||
} | ||
}; | ||
DeferredHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
if(this._isMonitored()) { this.context = void 0; } | ||
DeferredHandler.prototype.when = function(continuation) { | ||
if(this.resolved) { | ||
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.handler)); | ||
tasks.enqueue(new ContinuationTask(continuation, this.handler)); | ||
} else { | ||
this.consumers.push(resolve, notify, t, receiver, f, r, u); | ||
this.consumers.push(continuation); | ||
} | ||
@@ -477,2 +517,7 @@ }; | ||
DeferredHandler.prototype._fatal = function(context) { | ||
var c = typeof context === 'undefined' ? this.context : context; | ||
this.resolved && this.handler.join()._fatal(c); | ||
}; | ||
/** | ||
@@ -491,6 +536,2 @@ * Abstract base for handler that delegates to another handler | ||
DelegateHandler.prototype.join = function() { | ||
return this.handler.join(); | ||
}; | ||
DelegateHandler.prototype.inspect = function() { | ||
@@ -520,4 +561,4 @@ return this.join().inspect(); | ||
AsyncHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
tasks.enqueue(new RunHandlerTask(resolve, notify, t, receiver, f, r, u, this.join())); | ||
AsyncHandler.prototype.when = function(continuation) { | ||
tasks.enqueue(new ContinuationTask(continuation, this.join())); | ||
}; | ||
@@ -539,3 +580,3 @@ | ||
BoundHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
BoundHandler.prototype.when = function(continuation) { | ||
// Because handlers are allowed to be shared among promises, | ||
@@ -546,5 +587,5 @@ // each of which possibly having a different receiver, we have | ||
if(this.receiver !== void 0) { | ||
receiver = this.receiver; | ||
continuation.receiver = this.receiver; | ||
} | ||
this.join().when(resolve, notify, t, receiver, f, r, u); | ||
this.join().when(continuation); | ||
}; | ||
@@ -568,13 +609,12 @@ | ||
ThenableHandler.prototype.when = function(resolve, notify, t, receiver, f, r, u) { | ||
ThenableHandler.prototype.when = function(continuation) { | ||
if(!this.assimilated) { | ||
this.assimilated = true; | ||
this._assimilate(); | ||
assimilate(this); | ||
} | ||
DeferredHandler.prototype.when.call(this, resolve, notify, t, receiver, f, r, u); | ||
DeferredHandler.prototype.when.call(this, continuation); | ||
}; | ||
ThenableHandler.prototype._assimilate = function() { | ||
var h = this; | ||
this._try(this.untrustedThen, this.thenable, _resolve, _reject, _notify); | ||
function assimilate(h) { | ||
tryAssimilate(h.untrustedThen, h.thenable, _resolve, _reject, _notify); | ||
@@ -584,5 +624,5 @@ function _resolve(x) { h.resolve(x); } | ||
function _notify(x) { h.notify(x); } | ||
}; | ||
} | ||
ThenableHandler.prototype._try = function(then, thenable, resolve, reject, notify) { | ||
function tryAssimilate(then, thenable, resolve, reject, notify) { | ||
try { | ||
@@ -593,3 +633,3 @@ then.call(thenable, resolve, reject, notify); | ||
} | ||
}; | ||
} | ||
@@ -603,8 +643,6 @@ /** | ||
function FulfilledHandler(x) { | ||
Promise.createContext(this); | ||
this.value = x; | ||
this.state = 1; | ||
if(this._isMonitored()) { | ||
this._createContext(); | ||
} | ||
} | ||
@@ -618,12 +656,14 @@ | ||
FulfilledHandler.prototype.when = function(resolve, notify, t, receiver, f) { | ||
if(this._isMonitored()) { this._enterContext(); } | ||
FulfilledHandler.prototype.when = function(cont) { | ||
var x; | ||
var x = typeof f === 'function' | ||
? tryCatchReject(f, this.value, receiver) | ||
: this.value; | ||
if (typeof cont.fulfilled === 'function') { | ||
Promise.enterContext(this); | ||
x = tryCatchReject(cont.fulfilled, this.value, cont.receiver); | ||
Promise.exitContext(); | ||
} else { | ||
x = this.value; | ||
} | ||
if(this._isMonitored()) { this._exitContext(); } | ||
resolve.call(t, x); | ||
cont.resolve.call(cont.context, x); | ||
}; | ||
@@ -638,10 +678,9 @@ | ||
function RejectedHandler(x) { | ||
Promise.createContext(this); | ||
this.value = x; | ||
this.state = -1; | ||
this.handled = false; | ||
if(this._isMonitored()) { | ||
this.id = errorId++; | ||
this._createContext(); | ||
this._reportTrace(); | ||
} | ||
this._reportTrace(); | ||
} | ||
@@ -655,33 +694,42 @@ | ||
RejectedHandler.prototype.when = function(resolve, notify, t, receiver, f, r) { | ||
if(this._isMonitored()) { | ||
RejectedHandler.prototype.when = function(cont) { | ||
var x; | ||
if (typeof cont.rejected === 'function') { | ||
this._removeTrace(); | ||
this._enterContext(); | ||
Promise.enterContext(this); | ||
x = tryCatchReject(cont.rejected, this.value, cont.receiver); | ||
Promise.exitContext(); | ||
} else { | ||
x = promiseFromHandler(this); | ||
} | ||
var x = typeof r === 'function' | ||
? tryCatchReject(r, this.value, receiver) | ||
: promiseFromHandler(this); | ||
if(this._isMonitored()) { this._exitContext(); } | ||
resolve.call(t, x); | ||
cont.resolve.call(cont.context, x); | ||
}; | ||
RejectedHandler.prototype._reportTrace = function(context) { | ||
this._env.promiseMonitor.addTrace(this, context); | ||
Promise.onPotentiallyUnhandledRejection(this, context); | ||
}; | ||
RejectedHandler.prototype._removeTrace = function() { | ||
this._env.promiseMonitor.removeTrace(this); | ||
this.handled = true; | ||
Promise.onPotentiallyUnhandledRejectionHandled(this); | ||
}; | ||
RejectedHandler.prototype._fatal = function() { | ||
this._env.promiseMonitor.fatal(this); | ||
RejectedHandler.prototype._fatal = function(context) { | ||
Promise.onFatalRejection(this, context); | ||
}; | ||
// Execution context tracking for long stack traces | ||
// Unhandled rejection hooks | ||
// By default, everything is a noop | ||
var executionContext = []; | ||
var errorId = 0; | ||
// TODO: Better names: "annotate"? | ||
Promise.createContext | ||
= Promise.enterContext | ||
= Promise.exitContext | ||
= Promise.onPotentiallyUnhandledRejection | ||
= Promise.onPotentiallyUnhandledRejectionHandled | ||
= Promise.onFatalRejection | ||
= noop; | ||
@@ -715,9 +763,9 @@ // Errors and singletons | ||
*/ | ||
function RunHandlerTask(a, b, c, d, e, f, g, handler) { | ||
this.a=a;this.b=b;this.c=c;this.d=d;this.e=e;this.f=f;this.g=g; | ||
function ContinuationTask(continuation, handler) { | ||
this.continuation = continuation; | ||
this.handler = handler; | ||
} | ||
RunHandlerTask.prototype.run = function() { | ||
this.handler.join().when(this.a,this.b,this.c,this.d,this.e,this.f,this.g); | ||
ContinuationTask.prototype.run = function() { | ||
this.handler.join().when(this.continuation); | ||
}; | ||
@@ -738,13 +786,13 @@ | ||
// First progress handler is at index 1 | ||
for (var i = 1; i < q.length; i+=7) { | ||
this._notify(q[i], q[i+1], q[i+2], q[i+5]); | ||
for (var i = 0; i < q.length; ++i) { | ||
this._notify(q[i]); | ||
} | ||
}; | ||
ProgressTask.prototype._notify = function(notify, t, receiver, u) { | ||
var x = typeof u === 'function' | ||
? tryCatchReturn(u, this.value, receiver) | ||
ProgressTask.prototype._notify = function(continuation) { | ||
var x = typeof continuation.progress === 'function' | ||
? tryCatchReturn(continuation.progress, this.value, continuation.receiver) | ||
: this.value; | ||
notify.call(t, x); | ||
continuation.notify.call(continuation.context, x); | ||
}; | ||
@@ -776,2 +824,14 @@ | ||
/** | ||
* Same as above, but includes the extra argument parameter. | ||
* @private | ||
*/ | ||
function tryCatchReject2(f, x, y, thisArg) { | ||
try { | ||
return f.call(thisArg, x, y); | ||
} catch(e) { | ||
return reject(e); | ||
} | ||
} | ||
/** | ||
* Return f.call(thisArg, x), or if it throws, *return* the exception | ||
@@ -778,0 +838,0 @@ * @private |
@@ -13,4 +13,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
return makePromise({ | ||
scheduler: new Scheduler(async), | ||
monitor: typeof console !== 'undefined' ? console : void 0 | ||
scheduler: new Scheduler(async) | ||
}); | ||
@@ -17,0 +16,0 @@ |
@@ -29,5 +29,6 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
Scheduler.prototype.enqueue = function(task) { | ||
if(this._handlerQueue.push(task) === 1) { | ||
if(this._handlerQueue.length === 0) { | ||
this._enqueue(this.drainQueue); | ||
} | ||
this._handlerQueue.push(task); | ||
}; | ||
@@ -34,0 +35,0 @@ |
@@ -8,14 +8,8 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
var PromiseMonitor = require('./PromiseMonitor'); | ||
var ConsoleReporter = require('./ConsoleReporter'); | ||
var monitor = require('../monitor'); | ||
var Promise = require('../when').Promise; | ||
var promiseMonitor = new PromiseMonitor(new ConsoleReporter()); | ||
return monitor(Promise); | ||
if(typeof console !== 'undefined') { | ||
console.promiseMonitor = promiseMonitor; | ||
} | ||
return promiseMonitor; | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); |
@@ -22,3 +22,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
this._previouslyReported = false; | ||
this.warn(allHandledMsg); | ||
this.msg(allHandledMsg); | ||
} | ||
@@ -44,6 +44,7 @@ return; | ||
function initDefaultLogging() { | ||
var warn, groupStart, groupEnd; | ||
/*jshint maxcomplexity:7*/ | ||
var log, warn, groupStart, groupEnd; | ||
if(typeof console === 'undefined') { | ||
warn = consoleNotAvailable; | ||
log = warn = consoleNotAvailable; | ||
} else { | ||
@@ -56,2 +57,6 @@ if(typeof console.error === 'function' | ||
log = function(s) { | ||
console.log(s); | ||
}; | ||
if(typeof console.groupCollapsed === 'function') { | ||
@@ -71,3 +76,3 @@ groupStart = function(s) { | ||
&& typeof JSON !== 'undefined') { | ||
warn = function (x) { | ||
log = warn = function (x) { | ||
console.log(typeof x === 'string' ? x : JSON.stringify(x)); | ||
@@ -80,2 +85,3 @@ }; | ||
return { | ||
msg: log, | ||
warn: warn, | ||
@@ -82,0 +88,0 @@ groupStart: groupStart || warn, |
@@ -9,3 +9,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
var defaultStackJumpSeparator = 'from execution context:'; | ||
var defaultStackFilter = /(node|module|timers)\.js:|when([\/\\]{1,2}(lib|monitor|es6-shim)[\/\\]{1,2}|\.js)|(new\sPromise)\b|(\b(PromiseMonitor|ConsoleReporter|Scheduler|RunHandlerTask|ProgressTask|Promise|.*Handler)\.[\w_]\w\w+\b)|\b(tryCatch\w+|getHandler\w*)\b/i; | ||
var defaultStackFilter = /[\s\(\/\\](node|module|timers)\.js:|when([\/\\]{1,2}(lib|monitor|es6-shim)[\/\\]{1,2}|\.js)|(new\sPromise)\b|(\b(PromiseMonitor|ConsoleReporter|Scheduler|RunHandlerTask|ProgressTask|Promise|.*Handler)\.[\w_]\w\w+\b)|\b(tryCatch\w+|getHandler\w*)\b/i; | ||
@@ -15,6 +15,6 @@ var setTimer = require('../lib/timer').set; | ||
var executionContext = []; | ||
function PromiseMonitor(reporter) { | ||
this._traces = {}; | ||
this.traceTask = 0; | ||
this.logDelay = 100; | ||
this.logDelay = 0; | ||
this.stackFilter = defaultStackFilter; | ||
@@ -25,3 +25,2 @@ this.stackJumpSeparator = defaultStackJumpSeparator; | ||
this._reporter = reporter; | ||
if(typeof reporter.configurePromiseMonitor === 'function') { | ||
@@ -31,2 +30,5 @@ reporter.configurePromiseMonitor(this); | ||
this._traces = []; | ||
this._traceTask = 0; | ||
var self = this; | ||
@@ -38,25 +40,69 @@ this._doLogTraces = function() { | ||
PromiseMonitor.prototype.captureStack = function(host, at) { | ||
return error.captureStack(host, at); | ||
PromiseMonitor.prototype.monitor = function(Promise) { | ||
var self = this; | ||
Promise.createContext = function(p, context) { | ||
p.context = self.createContext(p, context); | ||
}; | ||
Promise.enterContext = function(p) { | ||
executionContext.push(p.context); | ||
}; | ||
Promise.exitContext = function() { | ||
executionContext.pop(); | ||
}; | ||
Promise.onPotentiallyUnhandledRejection = function(rejection, extraContext) { | ||
return self.addTrace(rejection, extraContext); | ||
}; | ||
Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) { | ||
return self.removeTrace(rejection); | ||
}; | ||
Promise.onFatalRejection = function(rejection, extraContext) { | ||
return self.fatal(rejection, extraContext); | ||
}; | ||
return this; | ||
}; | ||
PromiseMonitor.prototype.addTrace = function(handler, extraContext) { | ||
this._traces[handler.id] = { | ||
error: handler.value, | ||
context: handler.context, | ||
extraContext: extraContext | ||
PromiseMonitor.prototype.createContext = function(at, parentContext) { | ||
var context = { | ||
parent: parentContext || executionContext[executionContext.length - 1], | ||
stack: void 0 | ||
}; | ||
this.logTraces(); | ||
error.captureStack(context, at.constructor); | ||
return context; | ||
}; | ||
PromiseMonitor.prototype.removeTrace = function(handler) { | ||
if(handler.id in this._traces) { | ||
delete this._traces[handler.id]; | ||
this.logTraces(); | ||
PromiseMonitor.prototype.addTrace = function(handler, extraContext) { | ||
var t, i; | ||
for(i = this._traces.length-1; i >= 0; --i) { | ||
t = this._traces[i]; | ||
if(t.handler === handler) { | ||
break; | ||
} | ||
} | ||
if(i >= 0) { | ||
t.extraContext = extraContext; | ||
} else { | ||
this._traces.push({ | ||
handler: handler, | ||
extraContext: extraContext | ||
}); | ||
} | ||
this.logTraces(); | ||
}; | ||
PromiseMonitor.prototype.fatal = function(handler) { | ||
PromiseMonitor.prototype.removeTrace = function(/*handler*/) { | ||
this.logTraces(); | ||
}; | ||
PromiseMonitor.prototype.fatal = function(handler, extraContext) { | ||
var err = new Error(); | ||
err.stack = this._createLongTrace(handler.value, handler.context).join('\n'); | ||
err.stack = this._createLongTrace(handler.value, handler.context, extraContext).join('\n'); | ||
setTimer(function() { | ||
@@ -68,4 +114,4 @@ throw err; | ||
PromiseMonitor.prototype.logTraces = function() { | ||
if(!this.traceTask) { | ||
this.traceTask = setTimer(this._doLogTraces, this.logDelay); | ||
if(!this._traceTask) { | ||
this._traceTask = setTimer(this._doLogTraces, this.logDelay); | ||
} | ||
@@ -75,3 +121,4 @@ }; | ||
PromiseMonitor.prototype._logTraces = function() { | ||
this.traceTask = void 0; | ||
this._traceTask = void 0; | ||
this._traces = this._traces.filter(filterHandled); | ||
this._reporter.log(this.formatTraces(this._traces)); | ||
@@ -82,17 +129,9 @@ }; | ||
PromiseMonitor.prototype.formatTraces = function(traces) { | ||
var keys = Object.keys(traces); | ||
var formatted = []; | ||
var longTrace, t, i; | ||
for(i=0; i<keys.length; ++i) { | ||
t = traces[keys[i]]; | ||
longTrace = this._createLongTrace(t.error, t.context, t.extraContext); | ||
formatted.push(longTrace); | ||
} | ||
return formatted; | ||
return traces.map(function(t) { | ||
return this._createLongTrace(t.handler.value, t.handler.context, t.extraContext); | ||
}, this); | ||
}; | ||
PromiseMonitor.prototype._createLongTrace = function(e, context, extraContext) { | ||
var trace = error.parse(e) || []; | ||
var trace = error.parse(e) || [String(e) + ' (WARNING: non-Error used)']; | ||
trace = filterFrames(this.stackFilter, trace, 0); | ||
@@ -160,4 +199,8 @@ this._appendContext(trace, context); | ||
function filterHandled(t) { | ||
return !t.handler.handled; | ||
} | ||
return PromiseMonitor; | ||
}); | ||
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); |
73
node.js
@@ -14,10 +14,8 @@ /** @license MIT License (c) copyright 2013 original author or authors */ | ||
var when, Promise, slice, setTimer, _liftAll; | ||
var when = require('./when'); | ||
var Promise = when.Promise; | ||
var _liftAll = require('./lib/liftAll'); | ||
var setTimer = require('./lib/timer').set; | ||
var slice = Array.prototype.slice; | ||
when = require('./when'); | ||
Promise = when.Promise; | ||
_liftAll = require('./lib/liftAll'); | ||
setTimer = require('./lib/timer').set; | ||
slice = Array.prototype.slice; | ||
return { | ||
@@ -59,8 +57,8 @@ lift: lift, | ||
* | ||
* @param {function} func node-style function that will be called | ||
* @param {function} f node-style function that will be called | ||
* @param {Array} [args] array of arguments to func | ||
* @returns {Promise} promise for the value func passes to its callback | ||
*/ | ||
function apply(func, args) { | ||
return _apply(func, this, args || []); | ||
function apply(f, args) { | ||
return run(f, this, args || []); | ||
} | ||
@@ -72,19 +70,34 @@ | ||
*/ | ||
function _apply(func, thisArg, args) { | ||
return Promise.all(args).then(function(args) { | ||
return _applyDirect(func, thisArg, args); | ||
function run(f, thisArg, args) { | ||
var p = Promise._defer(); | ||
switch(args.length) { | ||
case 2: apply2(p, f, thisArg, args); break; | ||
case 1: apply1(p, f, thisArg, args); break; | ||
default: applyN(p, f, thisArg, args); | ||
} | ||
return p; | ||
} | ||
function applyN(p, f, thisArg, args) { | ||
Promise.all(args)._handler.chain(thisArg, function(args) { | ||
args.push(createCallback(p._handler)); | ||
f.apply(this, args); | ||
}); | ||
} | ||
/** | ||
* Apply helper that optimizes for small number of arguments | ||
* @private | ||
*/ | ||
function _applyDirect(func, thisArg, args) { | ||
var p = Promise._defer(); | ||
args.push(createCallback(p._handler)); | ||
func.apply(thisArg, args); | ||
return p; | ||
function apply2(p, f, thisArg, args) { | ||
Promise.resolve(args[0]).then(function(x) { | ||
Promise.resolve(args[1])._handler.chain(thisArg, function(y) { | ||
f.call(this, x, y, createCallback(p._handler)); | ||
}); | ||
}); | ||
} | ||
function apply1(p, f, thisArg, args) { | ||
Promise.resolve(args[0])._handler.chain(thisArg, function(x) { | ||
f.call(this, x, createCallback(p._handler)); | ||
}); | ||
} | ||
/** | ||
@@ -111,8 +124,8 @@ * Has the same behavior that {@link apply} has, with the difference that the | ||
* | ||
* @param {function} func node-style function that will be called | ||
* @param {function} f node-style function that will be called | ||
* @param {...*} [args] arguments that will be forwarded to the function | ||
* @returns {Promise} promise for the value func passes to its callback | ||
*/ | ||
function call(func /*, args... */) { | ||
return _apply(func, this, slice.call(arguments, 1)); | ||
function call(f /*, args... */) { | ||
return run(f, this, slice.call(arguments, 1)); | ||
} | ||
@@ -146,10 +159,10 @@ | ||
* | ||
* @param {Function} func node-style function to be bound | ||
* @param {...*} [args] arguments to be prepended for the new function | ||
* @param {Function} f node-style function to be lifted | ||
* @param {...*} [args] arguments to be prepended for the new function @deprecated | ||
* @returns {Function} a promise-returning function | ||
*/ | ||
function lift(func /*, args... */) { | ||
var args = slice.call(arguments, 1); | ||
function lift(f /*, args... */) { | ||
var args = arguments.length > 1 ? slice.call(arguments, 1) : []; | ||
return function() { | ||
return _apply(func, this, args.concat(slice.call(arguments))); | ||
return run(f, this, args.concat(slice.call(arguments))); | ||
}; | ||
@@ -156,0 +169,0 @@ } |
{ | ||
"name": "when", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "A lightweight Promises/A+ and when() implementation, plus other async goodies.", | ||
@@ -54,9 +54,14 @@ "keywords": [ | ||
"devDependencies": { | ||
"curl": "git://github.com/cujojs/curl", | ||
"poly": "git://github.com/cujojs/poly", | ||
"test-support": "~0.3", | ||
"promises-aplus-tests": "~2", | ||
"benchmark": "~1", | ||
"microtime": "~0", | ||
"browserify": "~2" | ||
"browserify": "~2", | ||
"buster": "~0.7", | ||
"jshint": "~2", | ||
"rest": "1.1.x", | ||
"optimist": "~0.6", | ||
"sauce-connect-launcher": "~0.4", | ||
"wd": "~0.2", | ||
"json5": "~0.2", | ||
"poly": "git://github.com/cujojs/poly#0.6.0" | ||
}, | ||
@@ -69,6 +74,8 @@ "main": "when", | ||
"scripts": { | ||
"test": "jshint . && buster test -e node -r specification && promises-aplus-tests test/promises-aplus-adapter.js --reporter spec", | ||
"ci": "npm test && sauceme -b test/browsers.json", | ||
"tunnel": "sauceme -m", | ||
"start": "buster static -e browser", | ||
"test": "jshint . && buster-test -e node && promises-aplus-tests test/promises-aplus-adapter.js", | ||
"build-browser-test": "browserify ./node_modules/poly/es5.js -o test/browser/es5.js && browserify ./test/*-test.js ./test/**/*-test.js -o test/browser/tests.js -x buster ", | ||
"browser-test": "npm run build-browser-test && buster-static -e browser -p 8080", | ||
"ci": "npm test && node test/sauce.js", | ||
"tunnel": "node test/sauce.js -m", | ||
"start": "buster-static -e browser", | ||
"benchmark": "node benchmark/promise && node benchmark/map", | ||
@@ -75,0 +82,0 @@ "browserify-es6": "browserify -s Promise es6-shim/Promise.browserify-es6.js --no-detect-globals -o es6-shim/Promise.js", |
@@ -14,8 +14,6 @@ /** @license MIT License (c) copyright 2012-2013 original author or authors */ | ||
var when, attempt, cancelable; | ||
var when = require('./when'); | ||
var attempt = when['try']; | ||
var cancelable = require('./cancelable'); | ||
when = require('./when'); | ||
attempt = when['try']; | ||
cancelable = require('./cancelable'); | ||
/** | ||
@@ -22,0 +20,0 @@ * Periodically execute the work function on the msec delay. The result of |
@@ -16,3 +16,3 @@ /** @license MIT License (c) copyright 2011-2013 original author or authors */ | ||
var resolve = require('./when').resolve; | ||
var when = require('./when'); | ||
@@ -23,3 +23,3 @@ /** | ||
return function timeout(msec, trigger) { | ||
return resolve(trigger).timeout(msec); | ||
return when(trigger).timeout(msec); | ||
}; | ||
@@ -26,0 +26,0 @@ }); |
41
when.js
@@ -8,3 +8,3 @@ /** @license MIT License (c) copyright 2010-2014 original author or authors */ | ||
* @author John Hann | ||
* @version 3.1.0 | ||
* @version 3.2.0 | ||
*/ | ||
@@ -17,2 +17,3 @@ (function(define) { 'use strict'; | ||
var flow = require('./lib/decorators/flow'); | ||
var fold = require('./lib/decorators/fold'); | ||
var inspect = require('./lib/decorators/inspect'); | ||
@@ -22,9 +23,11 @@ var generate = require('./lib/decorators/iterate'); | ||
var withThis = require('./lib/decorators/with'); | ||
var unhandledRejection = require('./lib/decorators/unhandledRejection'); | ||
var TimeoutError = require('./lib/TimeoutError'); | ||
var Promise = [array, flow, generate, progress, inspect, withThis, timed] | ||
.reduceRight(function(Promise, feature) { | ||
var Promise = [array, flow, fold, generate, progress, | ||
inspect, withThis, timed, unhandledRejection] | ||
.reduce(function(Promise, feature) { | ||
return feature(Promise); | ||
}, require('./lib/Promise')); | ||
var resolve = Promise.resolve; | ||
var slice = Array.prototype.slice; | ||
@@ -39,4 +42,4 @@ | ||
when.lift = lift; // lift a function to return promises | ||
when['try'] = tryCall; // call a function and return a promise | ||
when.attempt = tryCall; // alias for when.try | ||
when['try'] = attempt; // call a function and return a promise | ||
when.attempt = attempt; // alias for when.try | ||
@@ -63,4 +66,8 @@ when.iterate = Promise.iterate; // Generate a stream of promises | ||
// Error types | ||
when.TimeoutError = TimeoutError; | ||
/** | ||
* When x, which may be a promise, thenable, or non-promise value, | ||
* Get a trusted promise for x, or by transforming x with onFulfilled | ||
* | ||
@@ -73,3 +80,3 @@ * @param {*} x | ||
* rejected. | ||
* @param {function?} onProgress callback to be called when progress updates | ||
* @deprecated @param {function?} onProgress callback to be called when progress updates | ||
* are issued for x. | ||
@@ -80,5 +87,11 @@ * @returns {Promise} a new promise that will fulfill with the return | ||
*/ | ||
function when(x, onFulfilled, onRejected, onProgress) { | ||
var p = resolve(x); | ||
return arguments.length < 2 ? p : p.then(onFulfilled, onRejected, onProgress); | ||
function when(x, onFulfilled, onRejected) { | ||
var p = Promise.resolve(x); | ||
if(arguments.length < 2) { | ||
return p; | ||
} | ||
return arguments.length > 3 | ||
? p.then(onFulfilled, onRejected, arguments[3]) | ||
: p.then(onFulfilled, onRejected); | ||
} | ||
@@ -113,3 +126,3 @@ | ||
*/ | ||
function tryCall(f /*, args... */) { | ||
function attempt(f /*, args... */) { | ||
/*jshint validthis:true */ | ||
@@ -123,5 +136,5 @@ return _apply(f, this, slice.call(arguments, 1)); | ||
*/ | ||
function _apply(func, thisArg, args) { | ||
function _apply(f, thisArg, args) { | ||
return Promise.all(args).then(function(args) { | ||
return func.apply(thisArg, args); | ||
return f.apply(thisArg, args); | ||
}); | ||
@@ -128,0 +141,0 @@ } |
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
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
140706
46
4163
12
4