Update Q library
This commit is contained in:
parent
0e3d68bdd9
commit
0b89ccadf9
318
resource/q.js
318
resource/q.js
|
@ -2,8 +2,8 @@
|
||||||
/*jshint browser: true, node: true,
|
/*jshint browser: true, node: true,
|
||||||
curly: true, eqeqeq: true, noarg: true, nonew: true, trailing: true,
|
curly: true, eqeqeq: true, noarg: true, nonew: true, trailing: true,
|
||||||
undef: true */
|
undef: true */
|
||||||
/*global define: false, Q: true, msSetImmediate: false, setImmediate: false,
|
/*global define: false, Q: true, setImmediate: false,
|
||||||
ReturnValue: false, cajaVM: false, ses: false */
|
ReturnValue: false, cajaVM: false, ses: false, bootstrap: false */
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* Copyright 2009-2012 Kris Kowal under the terms of the MIT
|
* Copyright 2009-2012 Kris Kowal under the terms of the MIT
|
||||||
|
@ -67,14 +67,18 @@
|
||||||
// Common/Node/RequireJS, the module exports the Q API and when
|
// Common/Node/RequireJS, the module exports the Q API and when
|
||||||
// executed as a simple <script>, it creates a Q global instead.
|
// executed as a simple <script>, it creates a Q global instead.
|
||||||
|
|
||||||
// RequireJS
|
// Montage Require
|
||||||
if (typeof define === "function") {
|
if (typeof bootstrap === "function") {
|
||||||
define(definition);
|
bootstrap("promise", definition);
|
||||||
|
|
||||||
// CommonJS
|
// CommonJS
|
||||||
} else if (typeof exports === "object") {
|
} else if (typeof exports === "object") {
|
||||||
definition(void 0, exports);
|
definition(void 0, exports);
|
||||||
|
|
||||||
|
// RequireJS
|
||||||
|
} else if (typeof define === "function") {
|
||||||
|
define(definition);
|
||||||
|
|
||||||
// SES (Secure EcmaScript)
|
// SES (Secure EcmaScript)
|
||||||
} else if (typeof ses !== "undefined") {
|
} else if (typeof ses !== "undefined") {
|
||||||
if (!ses.ok()) {
|
if (!ses.ok()) {
|
||||||
|
@ -142,6 +146,11 @@
|
||||||
})(function (require, exports) {
|
})(function (require, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// All code after this point will be filtered from stack traces reported
|
||||||
|
// by Q.
|
||||||
|
var qStartingLine = captureLine();
|
||||||
|
var qFileName;
|
||||||
|
|
||||||
// shims
|
// shims
|
||||||
|
|
||||||
// used for fallback "defend" and in "allResolved"
|
// used for fallback "defend" and in "allResolved"
|
||||||
|
@ -163,12 +172,8 @@ var nextTick;
|
||||||
if (typeof process !== "undefined") {
|
if (typeof process !== "undefined") {
|
||||||
// node
|
// node
|
||||||
nextTick = process.nextTick;
|
nextTick = process.nextTick;
|
||||||
} else if (typeof msSetImmediate === "function") {
|
|
||||||
// IE 10 only, at the moment
|
|
||||||
// And yes, ``bind``ing to ``window`` is necessary O_o.
|
|
||||||
nextTick = msSetImmediate.bind(window);
|
|
||||||
} else if (typeof setImmediate === "function") {
|
} else if (typeof setImmediate === "function") {
|
||||||
// https://github.com/NobleJS/setImmediate
|
// In IE10, or use https://github.com/NobleJS/setImmediate
|
||||||
nextTick = setImmediate;
|
nextTick = setImmediate;
|
||||||
} else if (typeof MessageChannel !== "undefined") {
|
} else if (typeof MessageChannel !== "undefined") {
|
||||||
// modern browsers
|
// modern browsers
|
||||||
|
@ -212,7 +217,7 @@ if (Function.prototype.bind) {
|
||||||
uncurryThis = Function_bind.bind(Function_bind.call);
|
uncurryThis = Function_bind.bind(Function_bind.call);
|
||||||
} else {
|
} else {
|
||||||
uncurryThis = function (f) {
|
uncurryThis = function (f) {
|
||||||
return function (thisp) {
|
return function () {
|
||||||
return f.call.apply(f, arguments);
|
return f.call.apply(f, arguments);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -397,6 +402,14 @@ function formatSourcePosition(frame) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isInternalFrame(fileName, frame) {
|
||||||
|
if (fileName !== qFileName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var line = frame.getLineNumber();
|
||||||
|
return line >= qStartingLine && line <= qEndingLine;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieves an array of structured stack frames parsed from the ``stack``
|
* Retrieves an array of structured stack frames parsed from the ``stack``
|
||||||
* property of a given object.
|
* property of a given object.
|
||||||
|
@ -417,7 +430,7 @@ function getStackFrames(objectWithStack) {
|
||||||
return (
|
return (
|
||||||
fileName !== "module.js" &&
|
fileName !== "module.js" &&
|
||||||
fileName !== "node.js" &&
|
fileName !== "node.js" &&
|
||||||
fileName !== qFileName
|
!isInternalFrame(fileName, frame)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -429,16 +442,17 @@ function getStackFrames(objectWithStack) {
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
// discover own file name for filtering stack traces
|
// discover own file name and line number range for filtering stack
|
||||||
var qFileName;
|
// traces
|
||||||
if (Error.captureStackTrace) {
|
function captureLine() {
|
||||||
qFileName = (function () {
|
if (Error.captureStackTrace) {
|
||||||
var fileName;
|
var fileName, lineNumber;
|
||||||
|
|
||||||
var oldPrepareStackTrace = Error.prepareStackTrace;
|
var oldPrepareStackTrace = Error.prepareStackTrace;
|
||||||
|
|
||||||
Error.prepareStackTrace = function (error, frames) {
|
Error.prepareStackTrace = function (error, frames) {
|
||||||
fileName = frames[0].getFileName();
|
fileName = frames[1].getFileName();
|
||||||
|
lineNumber = frames[1].getLineNumber();
|
||||||
};
|
};
|
||||||
|
|
||||||
// teases call of temporary prepareStackTrace
|
// teases call of temporary prepareStackTrace
|
||||||
|
@ -447,17 +461,17 @@ if (Error.captureStackTrace) {
|
||||||
new Error().stack;
|
new Error().stack;
|
||||||
|
|
||||||
Error.prepareStackTrace = oldPrepareStackTrace;
|
Error.prepareStackTrace = oldPrepareStackTrace;
|
||||||
|
qFileName = fileName;
|
||||||
return fileName;
|
return lineNumber;
|
||||||
})();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deprecate(fn, name, alternative){
|
function deprecate(callback, name, alternative) {
|
||||||
return function () {
|
return function () {
|
||||||
if (typeof console !== "undefined" && typeof console.warn === "function"){
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
||||||
console.warn(name + " is deprecated, use " + alternative + " instead.");
|
console.warn(name + " is deprecated, use " + alternative + " instead.", new Error("").stack);
|
||||||
}
|
}
|
||||||
return fn.apply(fn,arguments);
|
return callback.apply(callback, arguments);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,15 +501,18 @@ function defer() {
|
||||||
// forward to the resolved promise. We coerce the resolution value to a
|
// forward to the resolved promise. We coerce the resolution value to a
|
||||||
// promise using the ref promise because it handles both fully
|
// promise using the ref promise because it handles both fully
|
||||||
// resolved values and other promises gracefully.
|
// resolved values and other promises gracefully.
|
||||||
var pending = [], value;
|
var pending = [], progressListeners = [], value;
|
||||||
|
|
||||||
var deferred = object_create(defer.prototype);
|
var deferred = object_create(defer.prototype);
|
||||||
var promise = object_create(makePromise.prototype);
|
var promise = object_create(makePromise.prototype);
|
||||||
|
|
||||||
promise.promiseSend = function () {
|
promise.promiseSend = function (op, _, __, progress) {
|
||||||
var args = array_slice(arguments);
|
var args = array_slice(arguments);
|
||||||
if (pending) {
|
if (pending) {
|
||||||
pending.push(args);
|
pending.push(args);
|
||||||
|
if (op === "when" && progress) {
|
||||||
|
progressListeners.push(progress);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nextTick(function () {
|
nextTick(function () {
|
||||||
value.promiseSend.apply(value, args);
|
value.promiseSend.apply(value, args);
|
||||||
|
@ -525,6 +542,7 @@ function defer() {
|
||||||
});
|
});
|
||||||
}, void 0);
|
}, void 0);
|
||||||
pending = void 0;
|
pending = void 0;
|
||||||
|
progressListeners = void 0;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,6 +553,17 @@ function defer() {
|
||||||
deferred.reject = function (exception) {
|
deferred.reject = function (exception) {
|
||||||
return become(reject(exception));
|
return become(reject(exception));
|
||||||
};
|
};
|
||||||
|
deferred.notify = function () {
|
||||||
|
if (pending) {
|
||||||
|
var args = arguments;
|
||||||
|
|
||||||
|
array_reduce(progressListeners, function (undefined, progressListener) {
|
||||||
|
nextTick(function () {
|
||||||
|
progressListener.apply(void 0, args);
|
||||||
|
});
|
||||||
|
}, void 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return deferred;
|
return deferred;
|
||||||
}
|
}
|
||||||
|
@ -561,18 +590,18 @@ defer.prototype.node = deprecate(defer.prototype.makeNodeResolver, "node", "make
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param makePromise {Function} a function that returns nothing and accepts
|
* @param makePromise {Function} a function that returns nothing and accepts
|
||||||
* the resolve and reject functions for a deferred.
|
* the resolve, reject, and notify functions for a deferred.
|
||||||
* @returns a promise that may be resolved with the given resolve and reject
|
* @returns a promise that may be resolved with the given resolve and reject
|
||||||
* functions, or rejected by a thrown exception in makePromise
|
* functions, or rejected by a thrown exception in makePromise
|
||||||
*/
|
*/
|
||||||
exports.promise = promise;
|
exports.promise = promise;
|
||||||
function promise(makePromise) {
|
function promise(makePromise) {
|
||||||
var deferred = defer();
|
var deferred = defer();
|
||||||
call(
|
fcall(
|
||||||
makePromise,
|
makePromise,
|
||||||
void 0,
|
|
||||||
deferred.resolve,
|
deferred.resolve,
|
||||||
deferred.reject
|
deferred.reject,
|
||||||
|
deferred.notify
|
||||||
).fail(deferred.reject);
|
).fail(deferred.reject);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
@ -610,7 +639,9 @@ function makePromise(descriptor, fallback, valueOf, exception) {
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
result = reject(exception);
|
result = reject(exception);
|
||||||
}
|
}
|
||||||
resolved(result);
|
if (resolved) {
|
||||||
|
resolved(result);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (valueOf) {
|
if (valueOf) {
|
||||||
|
@ -627,8 +658,12 @@ function makePromise(descriptor, fallback, valueOf, exception) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// provide thenables, CommonJS/Promises/A
|
// provide thenables, CommonJS/Promises/A
|
||||||
makePromise.prototype.then = function (fulfilled, rejected) {
|
makePromise.prototype.then = function (fulfilled, rejected, progressed) {
|
||||||
return when(this, fulfilled, rejected);
|
return when(this, fulfilled, rejected, progressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
makePromise.prototype.thenResolve = function (value) {
|
||||||
|
return when(this, function () { return value; });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Chainable methods
|
// Chainable methods
|
||||||
|
@ -644,9 +679,12 @@ array_reduce(
|
||||||
"all", "allResolved",
|
"all", "allResolved",
|
||||||
"view", "viewInfo",
|
"view", "viewInfo",
|
||||||
"timeout", "delay",
|
"timeout", "delay",
|
||||||
"catch", "finally", "fail", "fin", "end"
|
"catch", "finally", "fail", "fin", "progress", "end", "done",
|
||||||
|
"ncall", "napply", "nbind",
|
||||||
|
"npost", "ninvoke",
|
||||||
|
"nend"
|
||||||
],
|
],
|
||||||
function (prev, name) {
|
function (undefined, name) {
|
||||||
makePromise.prototype[name] = function () {
|
makePromise.prototype[name] = function () {
|
||||||
return exports[name].apply(
|
return exports[name].apply(
|
||||||
exports,
|
exports,
|
||||||
|
@ -726,12 +764,21 @@ function isRejected(object) {
|
||||||
|
|
||||||
var rejections = [];
|
var rejections = [];
|
||||||
var errors = [];
|
var errors = [];
|
||||||
if (typeof window !== "undefined" && window.console) {
|
var errorsDisplayed;
|
||||||
// This promise library consumes exceptions thrown in handlers so
|
function displayErrors() {
|
||||||
// they can be handled by a subsequent promise. The rejected
|
if (
|
||||||
// promises get added to this array when they are created, and
|
!errorsDisplayed &&
|
||||||
// removed when they are handled.
|
typeof window !== "undefined" &&
|
||||||
console.log("Should be empty:", errors);
|
!window.Touch &&
|
||||||
|
window.console
|
||||||
|
) {
|
||||||
|
// This promise library consumes exceptions thrown in handlers so
|
||||||
|
// they can be handled by a subsequent promise. The rejected
|
||||||
|
// promises get added to this array when they are created, and
|
||||||
|
// removed when they are handled.
|
||||||
|
console.log("Should be empty:", errors);
|
||||||
|
}
|
||||||
|
errorsDisplayed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -753,12 +800,13 @@ function reject(exception) {
|
||||||
}
|
}
|
||||||
return rejected ? rejected(exception) : reject(exception);
|
return rejected ? rejected(exception) : reject(exception);
|
||||||
}
|
}
|
||||||
}, function fallback(op) {
|
}, function fallback() {
|
||||||
return reject(exception);
|
return reject(exception);
|
||||||
}, function valueOf() {
|
}, function valueOf() {
|
||||||
return this;
|
return this;
|
||||||
}, exception);
|
}, exception);
|
||||||
// note that the error has not been handled
|
// note that the error has not been handled
|
||||||
|
displayErrors();
|
||||||
rejections.push(rejection);
|
rejections.push(rejection);
|
||||||
errors.push(exception);
|
errors.push(exception);
|
||||||
return rejection;
|
return rejection;
|
||||||
|
@ -778,24 +826,35 @@ function resolve(object) {
|
||||||
if (isPromise(object)) {
|
if (isPromise(object)) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
// In order to break infinite recursion or loops between `then` and
|
||||||
|
// `resolve`, it is necessary to attempt to extract fulfilled values
|
||||||
|
// out of foreign promise implementations before attempting to wrap
|
||||||
|
// them as unresolved promises. It is my hope that other
|
||||||
|
// implementations will implement `valueOf` to synchronously extract
|
||||||
|
// the fulfillment value from their fulfilled promises. If the
|
||||||
|
// other promise library does not implement `valueOf`, the
|
||||||
|
// implementations on primordial prototypes are harmless.
|
||||||
|
object = valueOf(object);
|
||||||
// assimilate thenables, CommonJS/Promises/A
|
// assimilate thenables, CommonJS/Promises/A
|
||||||
if (object && typeof object.then === "function") {
|
if (object && typeof object.then === "function") {
|
||||||
var result = defer();
|
var deferred = defer();
|
||||||
object.then(result.resolve, result.reject);
|
object.then(deferred.resolve, deferred.reject, deferred.notify);
|
||||||
return result.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
return makePromise({
|
return makePromise({
|
||||||
"when": function (rejected) {
|
"when": function () {
|
||||||
return object;
|
return object;
|
||||||
},
|
},
|
||||||
"get": function (name) {
|
"get": function (name) {
|
||||||
return object[name];
|
return object[name];
|
||||||
},
|
},
|
||||||
"put": function (name, value) {
|
"put": function (name, value) {
|
||||||
return object[name] = value;
|
object[name] = value;
|
||||||
|
return object;
|
||||||
},
|
},
|
||||||
"del": function (name) {
|
"del": function (name) {
|
||||||
return delete object[name];
|
delete object[name];
|
||||||
|
return object;
|
||||||
},
|
},
|
||||||
"post": function (name, value) {
|
"post": function (name, value) {
|
||||||
return object[name].apply(object, value);
|
return object[name].apply(object, value);
|
||||||
|
@ -846,7 +905,7 @@ exports.master = master;
|
||||||
function master(object) {
|
function master(object) {
|
||||||
return makePromise({
|
return makePromise({
|
||||||
"isDef": function () {}
|
"isDef": function () {}
|
||||||
}, function fallback(op) {
|
}, function fallback() {
|
||||||
var args = array_slice(arguments);
|
var args = array_slice(arguments);
|
||||||
return send.apply(void 0, [object].concat(args));
|
return send.apply(void 0, [object].concat(args));
|
||||||
}, function () {
|
}, function () {
|
||||||
|
@ -862,7 +921,7 @@ function viewInfo(object, info) {
|
||||||
"viewInfo": function () {
|
"viewInfo": function () {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
}, function fallback(op) {
|
}, function fallback() {
|
||||||
var args = array_slice(arguments);
|
var args = array_slice(arguments);
|
||||||
return send.apply(void 0, [object].concat(args));
|
return send.apply(void 0, [object].concat(args));
|
||||||
}, function () {
|
}, function () {
|
||||||
|
@ -906,13 +965,14 @@ function view(object) {
|
||||||
* called, but not both.
|
* called, but not both.
|
||||||
* 3. that fulfilled and rejected will not be called in this turn.
|
* 3. that fulfilled and rejected will not be called in this turn.
|
||||||
*
|
*
|
||||||
* @param value promise or immediate reference to observe
|
* @param value promise or immediate reference to observe
|
||||||
* @param fulfilled function to be called with the fulfilled value
|
* @param fulfilled function to be called with the fulfilled value
|
||||||
* @param rejected function to be called with the rejection exception
|
* @param rejected function to be called with the rejection exception
|
||||||
|
* @param progressed function to be called on any progress notifications
|
||||||
* @return promise for the return value from the invoked callback
|
* @return promise for the return value from the invoked callback
|
||||||
*/
|
*/
|
||||||
exports.when = when;
|
exports.when = when;
|
||||||
function when(value, fulfilled, rejected) {
|
function when(value, fulfilled, rejected, progressed) {
|
||||||
var deferred = defer();
|
var deferred = defer();
|
||||||
var done = false; // ensure the untrusted promise makes at most a
|
var done = false; // ensure the untrusted promise makes at most a
|
||||||
// single call to one of the callbacks
|
// single call to one of the callbacks
|
||||||
|
@ -933,26 +993,30 @@ function when(value, fulfilled, rejected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resolvedValue = resolve(value);
|
||||||
nextTick(function () {
|
nextTick(function () {
|
||||||
resolve(value).promiseSend("when", function (value) {
|
resolvedValue.promiseSend("when", function (value) {
|
||||||
if (done) {
|
if (done) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
resolve(value).promiseSend("when", function (value) {
|
|
||||||
deferred.resolve(_fulfilled(value));
|
deferred.resolve(_fulfilled(value));
|
||||||
}, function (exception) {
|
|
||||||
deferred.resolve(_rejected(exception));
|
|
||||||
});
|
|
||||||
}, function (exception) {
|
}, function (exception) {
|
||||||
if (done) {
|
if (done) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
deferred.resolve(_rejected(exception));
|
deferred.resolve(_rejected(exception));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Progress listeners need to be attached in the current tick.
|
||||||
|
if (progressed) {
|
||||||
|
resolvedValue.promiseSend("when", void 0, void 0, progressed);
|
||||||
|
}
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,8 +1032,10 @@ function when(value, fulfilled, rejected) {
|
||||||
*/
|
*/
|
||||||
exports.spread = spread;
|
exports.spread = spread;
|
||||||
function spread(promise, fulfilled, rejected) {
|
function spread(promise, fulfilled, rejected) {
|
||||||
return when(promise, function (values) {
|
return when(promise, function (valuesOrPromises) {
|
||||||
return fulfilled.apply(void 0, values);
|
return all(valuesOrPromises).then(function (values) {
|
||||||
|
return fulfilled.apply(void 0, values);
|
||||||
|
});
|
||||||
}, rejected);
|
}, rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,6 +1115,30 @@ function _return(value) {
|
||||||
throw new QReturnValue(value);
|
throw new QReturnValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The promised function decorator ensures that any promise arguments
|
||||||
|
* are resolved and passed as values (`this` is also resolved and passed
|
||||||
|
* as a value). It will also ensure that the result of a function is
|
||||||
|
* always a promise.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var add = Q.promised(function (a, b) {
|
||||||
|
* return a + b;
|
||||||
|
* });
|
||||||
|
* add(Q.resolve(a), Q.resolve(B));
|
||||||
|
*
|
||||||
|
* @param {function} callback The function to decorate
|
||||||
|
* @returns {function} a function that has been decorated.
|
||||||
|
*/
|
||||||
|
exports.promised = promised;
|
||||||
|
function promised(callback) {
|
||||||
|
return function () {
|
||||||
|
return all([this, all(arguments)]).spread(function (self, args) {
|
||||||
|
return callback.apply(self, args);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a promise method that can be used to safely observe resolution of
|
* Constructs a promise method that can be used to safely observe resolution of
|
||||||
* a promise for an arbitrarily named method like "propfind" in a future turn.
|
* a promise for an arbitrarily named method like "propfind" in a future turn.
|
||||||
|
@ -1268,13 +1358,20 @@ function all(promises) {
|
||||||
}
|
}
|
||||||
var deferred = defer();
|
var deferred = defer();
|
||||||
array_reduce(promises, function (undefined, promise, index) {
|
array_reduce(promises, function (undefined, promise, index) {
|
||||||
when(promise, function (value) {
|
if (isFulfilled(promise)) {
|
||||||
promises[index] = value;
|
promises[index] = valueOf(promise);
|
||||||
if (--countDown === 0) {
|
if (--countDown === 0) {
|
||||||
deferred.resolve(promises);
|
deferred.resolve(promises);
|
||||||
}
|
}
|
||||||
})
|
} else {
|
||||||
.fail(deferred.reject);
|
when(promise, function (value) {
|
||||||
|
promises[index] = value;
|
||||||
|
if (--countDown === 0) {
|
||||||
|
deferred.resolve(promises);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fail(deferred.reject);
|
||||||
|
}
|
||||||
}, void 0);
|
}, void 0);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
});
|
});
|
||||||
|
@ -1315,6 +1412,20 @@ function fail(promise, rejected) {
|
||||||
return when(promise, void 0, rejected);
|
return when(promise, void 0, rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a listener that can respond to progress notifications from a
|
||||||
|
* promise's originating deferred. This listener receives the exact arguments
|
||||||
|
* passed to ``deferred.notify``.
|
||||||
|
* @param {Any*} promise for something
|
||||||
|
* @param {Function} callback to receive any progress notifications
|
||||||
|
* @returns the given promise, unchanged
|
||||||
|
*/
|
||||||
|
exports.progress = progress;
|
||||||
|
function progress(promise, progressed) {
|
||||||
|
when(promise, void 0, void 0, progressed);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an opportunity to observe the rejection of a promise,
|
* Provides an opportunity to observe the rejection of a promise,
|
||||||
* regardless of whether the promise is fulfilled or rejected. Forwards
|
* regardless of whether the promise is fulfilled or rejected. Forwards
|
||||||
|
@ -1346,30 +1457,49 @@ function fin(promise, callback) {
|
||||||
* @param {Any*} promise at the end of a chain of promises
|
* @param {Any*} promise at the end of a chain of promises
|
||||||
* @returns nothing
|
* @returns nothing
|
||||||
*/
|
*/
|
||||||
exports.end = end; // XXX stopgap
|
exports.end = deprecate(done, "end", "done"); // XXX deprecated, use done
|
||||||
function end(promise) {
|
exports.done = done;
|
||||||
when(promise, void 0, function (error) {
|
function done(promise, fulfilled, rejected, progress) {
|
||||||
|
function onUnhandledError(error) {
|
||||||
// forward to a future turn so that ``when``
|
// forward to a future turn so that ``when``
|
||||||
// does not catch it and turn it into a rejection.
|
// does not catch it and turn it into a rejection.
|
||||||
nextTick(function () {
|
nextTick(function () {
|
||||||
// If possible (that is, if in V8), transform the error stack
|
// If possible (that is, if in V8), transform the error stack
|
||||||
// trace by removing Node and Q cruft, then concatenating with
|
// trace by removing Node and Q cruft, then concatenating with
|
||||||
// the stack trace of the promise we are ``end``ing. See #57.
|
// the stack trace of the promise we are ``done``ing. See #57.
|
||||||
if (Error.captureStackTrace && typeof error === "object" &&
|
var errorStackFrames;
|
||||||
"stack" in error) {
|
if (
|
||||||
var errorStackFrames = getStackFrames(error);
|
Error.captureStackTrace &&
|
||||||
|
typeof error === "object" &&
|
||||||
|
(errorStackFrames = getStackFrames(error))
|
||||||
|
) {
|
||||||
var promiseStackFrames = getStackFrames(promise);
|
var promiseStackFrames = getStackFrames(promise);
|
||||||
|
|
||||||
var combinedStackFrames = errorStackFrames.concat(
|
// Check to make sure the stack trace hasn't already been
|
||||||
"From previous event:",
|
// rendered (possibly by us).
|
||||||
promiseStackFrames
|
if (typeof errorStackFrames !== "string") {
|
||||||
);
|
var combinedStackFrames = errorStackFrames.concat(
|
||||||
error.stack = formatStackTrace(error, combinedStackFrames);
|
"From previous event:",
|
||||||
|
promiseStackFrames
|
||||||
|
);
|
||||||
|
error.stack = formatStackTrace(error, combinedStackFrames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error;
|
if (exports.onerror) {
|
||||||
|
exports.onerror(error);
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Avoid unnecessary `nextTick`ing via an unnecessary `when`.
|
||||||
|
var promiseToHandle = fulfilled || rejected || progress ?
|
||||||
|
when(promise, fulfilled, rejected, progress) :
|
||||||
|
promise;
|
||||||
|
|
||||||
|
fail(promiseToHandle, onUnhandledError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1419,7 +1549,7 @@ function delay(promise, timeout) {
|
||||||
* Passes a continuation to a Node function, which is called with a given
|
* Passes a continuation to a Node function, which is called with a given
|
||||||
* `this` value and arguments provided as an array, and returns a promise.
|
* `this` value and arguments provided as an array, and returns a promise.
|
||||||
*
|
*
|
||||||
* var FS = require("fs");
|
* var FS = (require)("fs");
|
||||||
* Q.napply(FS.readFile, FS, [__filename])
|
* Q.napply(FS.readFile, FS, [__filename])
|
||||||
* .then(function (content) {
|
* .then(function (content) {
|
||||||
* })
|
* })
|
||||||
|
@ -1434,7 +1564,7 @@ function napply(callback, thisp, args) {
|
||||||
* Passes a continuation to a Node function, which is called with a given
|
* Passes a continuation to a Node function, which is called with a given
|
||||||
* `this` value and arguments provided individually, and returns a promise.
|
* `this` value and arguments provided individually, and returns a promise.
|
||||||
*
|
*
|
||||||
* var FS = require("fs");
|
* var FS = (require)("fs");
|
||||||
* Q.ncall(FS.readFile, FS, __filename)
|
* Q.ncall(FS.readFile, FS, __filename)
|
||||||
* .then(function (content) {
|
* .then(function (content) {
|
||||||
* })
|
* })
|
||||||
|
@ -1452,7 +1582,7 @@ function ncall(callback, thisp /*, ...args*/) {
|
||||||
*
|
*
|
||||||
* Q.nbind(FS.readFile, FS)(__filename)
|
* Q.nbind(FS.readFile, FS)(__filename)
|
||||||
* .then(console.log)
|
* .then(console.log)
|
||||||
* .end()
|
* .done()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
exports.nbind = nbind;
|
exports.nbind = nbind;
|
||||||
|
@ -1509,6 +1639,24 @@ function ninvoke(object, name /*, ...args*/) {
|
||||||
return napply(object[name], object, args);
|
return napply(object[name], object, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
defend(exports);
|
exports.nend = nend;
|
||||||
|
function nend(promise, nodeback) {
|
||||||
|
if (nodeback) {
|
||||||
|
promise.then(function (value) {
|
||||||
|
nextTick(function () {
|
||||||
|
nodeback(null, value);
|
||||||
|
});
|
||||||
|
}, function (error) {
|
||||||
|
nextTick(function () {
|
||||||
|
nodeback(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All code before this point will be filtered from stack traces.
|
||||||
|
var qEndingLine = captureLine();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user