1 // vim:ts=4:sts=4:sw=4:
4 * Copyright 2009-2012 Kris Kowal under the terms of the MIT
5 * license found at http://github.com/kriskowal/q/raw/master/LICENSE
7 * With parts by Tyler Close
8 * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
9 * at http://www.opensource.org/licenses/mit-license.html
10 * Forked at ref_send.js version: 2009-05-11
12 * With parts by Mark Miller
13 * Copyright (C) 2011 Google Inc.
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
19 * http://www.apache.org/licenses/LICENSE-2.0
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
29 (function (definition) {
32 // This file will function properly as a <script> tag, or a module
33 // using CommonJS and NodeJS or RequireJS module formats. In
34 // Common/Node/RequireJS, the module exports the Q API and when
35 // executed as a simple <script>, it creates a Q global instead.
38 if (typeof bootstrap === "function") {
39 bootstrap("promise", definition);
42 } else if (typeof exports === "object" && typeof module === "object") {
43 module.exports = definition();
46 } else if (typeof define === "function" && define.amd) {
49 // SES (Secure EcmaScript)
50 } else if (typeof ses !== "undefined") {
54 ses.makeQ = definition;
58 } else if (typeof window !== "undefined" || typeof self !== "undefined") {
59 // Prefer window over self for add-on scripts. Use self for
60 // non-windowed contexts.
61 var global = typeof window !== "undefined" ? window : self;
63 // Get the `window` object, save the previous Q global
64 // and initialize Q as a global.
65 var previousQ = global.Q;
66 global.Q = definition();
68 // Add a noConflict function so Q can be removed from the
70 global.Q.noConflict = function () {
76 throw new Error("This environment was not anticipated by Q. Please file a bug.");
82 var hasStacks = false;
86 hasStacks = !!e.stack;
89 // All code after this point will be filtered from stack traces reported
91 var qStartingLine = captureLine();
96 // used for fallback in "allResolved"
97 var noop = function () {};
99 // Use the fastest possible means to execute a task in a future turn
100 // of the event loop.
101 var nextTick =(function () {
102 // linked list of tasks (single, with head node)
103 var head = {task: void 0, next: null};
105 var flushing = false;
106 var requestTick = void 0;
107 var isNodeJS = false;
108 // queue for late tasks, used by unhandled rejection tracking
112 /* jshint loopfunc: true */
119 domain = head.domain;
122 head.domain = void 0;
125 runSingle(task, domain);
128 while (laterQueue.length) {
129 task = laterQueue.pop();
134 // runs a single function in the async queue
135 function runSingle(task, domain) {
141 // In node, uncaught exceptions are considered fatal errors.
142 // Re-throw them synchronously to interrupt flushing!
144 // Ensure continuation if the uncaught exception is suppressed
145 // listening "uncaughtException" events (as domains does).
146 // Continue in next event to avoid tick recursion.
150 setTimeout(flush, 0);
158 // In browsers, uncaught exceptions are not fatal.
159 // Re-throw them asynchronously to avoid slow-downs.
160 setTimeout(function () {
171 nextTick = function (task) {
174 domain: isNodeJS && process.domain,
184 if (typeof process === "object" &&
185 process.toString() === "[object process]" && process.nextTick) {
186 // Ensure Q is in a real Node environment, with a `process.nextTick`.
187 // To see through fake Node environments:
188 // * Mocha test runner - exposes a `process` global without a `nextTick`
189 // * Browserify - exposes a `process.nexTick` function that uses
190 // `setTimeout`. In this case `setImmediate` is preferred because
191 // it is faster. Browserify's `process.toString()` yields
192 // "[object Object]", while in a real Node environment
193 // `process.nextTick()` yields "[object process]".
196 requestTick = function () {
197 process.nextTick(flush);
200 } else if (typeof setImmediate === "function") {
201 // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
202 if (typeof window !== "undefined") {
203 requestTick = setImmediate.bind(window, flush);
205 requestTick = function () {
210 } else if (typeof MessageChannel !== "undefined") {
212 // http://www.nonblocking.io/2011/06/windownexttick.html
213 var channel = new MessageChannel();
214 // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
215 // working message ports the first time a page loads.
216 channel.port1.onmessage = function () {
217 requestTick = requestPortTick;
218 channel.port1.onmessage = flush;
221 var requestPortTick = function () {
222 // Opera requires us to provide a message payload, regardless of
223 // whether we use it.
224 channel.port2.postMessage(0);
226 requestTick = function () {
227 setTimeout(flush, 0);
233 requestTick = function () {
234 setTimeout(flush, 0);
237 // runs a task after all other tasks have been run
238 // this is useful for unhandled rejection tracking that needs to happen
239 // after all `then`d tasks have been run.
240 nextTick.runAfter = function (task) {
241 laterQueue.push(task);
250 // Attempt to make generics safe in the face of downstream
252 // There is no situation where this is necessary.
253 // If you need a security guarantee, these primordials need to be
254 // deeply frozen anyway, and if you don’t need a security guarantee,
255 // this is just plain paranoid.
256 // However, this **might** have the nice side-effect of reducing the size of
257 // the minified code by reducing x.call() to merely x()
258 // See Mark Miller’s explanation of what this does.
259 // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
260 var call = Function.call;
261 function uncurryThis(f) {
263 return call.apply(f, arguments);
266 // This is equivalent, but slower:
267 // uncurryThis = Function_bind.bind(Function_bind.call);
268 // http://jsperf.com/uncurrythis
270 var array_slice = uncurryThis(Array.prototype.slice);
272 var array_reduce = uncurryThis(
273 Array.prototype.reduce || function (callback, basis) {
275 length = this.length;
276 // concerning the initial value, if one is not provided
277 if (arguments.length === 1) {
278 // seek to the first value in the array, accounting
279 // for the possibility that is is a sparse array
282 basis = this[index++];
285 if (++index >= length) {
286 throw new TypeError();
291 for (; index < length; index++) {
292 // account for the possibility that the array is sparse
294 basis = callback(basis, this[index], index);
301 var array_indexOf = uncurryThis(
302 Array.prototype.indexOf || function (value) {
303 // not a very good shim, but good enough for our one use of it
304 for (var i = 0; i < this.length; i++) {
305 if (this[i] === value) {
313 var array_map = uncurryThis(
314 Array.prototype.map || function (callback, thisp) {
317 array_reduce(self, function (undefined, value, index) {
318 collect.push(callback.call(thisp, value, index, self));
324 var object_create = Object.create || function (prototype) {
326 Type.prototype = prototype;
330 var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
332 var object_keys = Object.keys || function (object) {
334 for (var key in object) {
335 if (object_hasOwnProperty(object, key)) {
342 var object_toString = uncurryThis(Object.prototype.toString);
344 function isObject(value) {
345 return value === Object(value);
348 // generator related shims
350 // FIXME: Remove this function once ES6 generators are in SpiderMonkey.
351 function isStopIteration(exception) {
353 object_toString(exception) === "[object StopIteration]" ||
354 exception instanceof QReturnValue
358 // FIXME: Remove this helper and Q.return once ES6 generators are in
361 if (typeof ReturnValue !== "undefined") {
362 QReturnValue = ReturnValue;
364 QReturnValue = function (value) {
371 var STACK_JUMP_SEPARATOR = "From previous event:";
373 function makeStackTraceLong(error, promise) {
374 // If possible, transform the error stack trace by removing Node and Q
375 // cruft, then concatenating with the stack trace of `promise`. See #57.
378 typeof error === "object" &&
381 error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
384 for (var p = promise; !!p; p = p.source) {
386 stacks.unshift(p.stack);
389 stacks.unshift(error.stack);
391 var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
392 error.stack = filterStackString(concatedStacks);
396 function filterStackString(stackString) {
397 var lines = stackString.split("\n");
398 var desiredLines = [];
399 for (var i = 0; i < lines.length; ++i) {
402 if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
403 desiredLines.push(line);
406 return desiredLines.join("\n");
409 function isNodeFrame(stackLine) {
410 return stackLine.indexOf("(module.js:") !== -1 ||
411 stackLine.indexOf("(node.js:") !== -1;
414 function getFileNameAndLineNumber(stackLine) {
415 // Named functions: "at functionName (filename:lineNumber:columnNumber)"
416 // In IE10 function name can have spaces ("Anonymous function") O_o
417 var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
419 return [attempt1[1], Number(attempt1[2])];
422 // Anonymous functions: "at filename:lineNumber:columnNumber"
423 var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
425 return [attempt2[1], Number(attempt2[2])];
428 // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
429 var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
431 return [attempt3[1], Number(attempt3[2])];
435 function isInternalFrame(stackLine) {
436 var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
438 if (!fileNameAndLineNumber) {
442 var fileName = fileNameAndLineNumber[0];
443 var lineNumber = fileNameAndLineNumber[1];
445 return fileName === qFileName &&
446 lineNumber >= qStartingLine &&
447 lineNumber <= qEndingLine;
450 // discover own file name and line number range for filtering stack
452 function captureLine() {
460 var lines = e.stack.split("\n");
461 var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
462 var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
463 if (!fileNameAndLineNumber) {
467 qFileName = fileNameAndLineNumber[0];
468 return fileNameAndLineNumber[1];
472 function deprecate(callback, name, alternative) {
474 if (typeof console !== "undefined" &&
475 typeof console.warn === "function") {
476 console.warn(name + " is deprecated, use " + alternative +
477 " instead.", new Error("").stack);
479 return callback.apply(callback, arguments);
484 // beginning of real work
487 * Constructs a promise for an immediate reference, passes promises through, or
488 * coerces promises from different systems.
489 * @param value immediate reference or promise
492 // If the object is already a Promise, return it directly. This enables
493 // the resolve function to both be used to created references from objects,
494 // but to tolerably coerce non-promises to promises.
495 if (value instanceof Promise) {
499 // assimilate thenables
500 if (isPromiseAlike(value)) {
501 return coerce(value);
503 return fulfill(value);
509 * Performs a task in a future turn of the event loop.
510 * @param {Function} task
512 Q.nextTick = nextTick;
515 * Controls whether or not long stack traces will be on
517 Q.longStackSupport = false;
519 // enable long stacks if Q_DEBUG is set
520 if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
521 Q.longStackSupport = true;
525 * Constructs a {promise, resolve, reject} object.
527 * `resolve` is a callback to invoke with a more resolved value for the
528 * promise. To fulfill the promise, invoke `resolve` with any value that is
529 * not a thenable. To reject the promise, invoke `resolve` with a rejected
530 * thenable, or invoke `reject` with the reason directly. To resolve the
531 * promise to another thenable, thus putting it in the same state, invoke
532 * `resolve` with that other thenable.
536 // if "messages" is an "Array", that indicates that the promise has not yet
537 // been resolved. If it is "undefined", it has been resolved. Each
538 // element of the messages array is itself an array of complete arguments to
539 // forward to the resolved promise. We coerce the resolution value to a
540 // promise using the `resolve` function because it handles both fully
541 // non-thenable values and other thenables gracefully.
542 var messages = [], progressListeners = [], resolvedPromise;
544 var deferred = object_create(defer.prototype);
545 var promise = object_create(Promise.prototype);
547 promise.promiseDispatch = function (resolve, op, operands) {
548 var args = array_slice(arguments);
551 if (op === "when" && operands[1]) { // progress operand
552 progressListeners.push(operands[1]);
555 Q.nextTick(function () {
556 resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
562 promise.valueOf = function () {
566 var nearerValue = nearer(resolvedPromise);
567 if (isPromise(nearerValue)) {
568 resolvedPromise = nearerValue; // shorten chain
573 promise.inspect = function () {
574 if (!resolvedPromise) {
575 return { state: "pending" };
577 return resolvedPromise.inspect();
580 if (Q.longStackSupport && hasStacks) {
584 // NOTE: don't try to use `Error.captureStackTrace` or transfer the
585 // accessor around; that causes memory leaks as per GH-111. Just
586 // reify the stack trace as a string ASAP.
588 // At the same time, cut off the first line; it's always just
589 // "[object Promise]\n", as per the `toString`.
590 promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
594 // NOTE: we do the checks for `resolvedPromise` in each method, instead of
595 // consolidating them into `become`, since otherwise we'd create new
596 // promises with the lines `become(whatever(value))`. See e.g. GH-252.
598 function become(newPromise) {
599 resolvedPromise = newPromise;
600 promise.source = newPromise;
602 array_reduce(messages, function (undefined, message) {
603 Q.nextTick(function () {
604 newPromise.promiseDispatch.apply(newPromise, message);
609 progressListeners = void 0;
612 deferred.promise = promise;
613 deferred.resolve = function (value) {
614 if (resolvedPromise) {
621 deferred.fulfill = function (value) {
622 if (resolvedPromise) {
626 become(fulfill(value));
628 deferred.reject = function (reason) {
629 if (resolvedPromise) {
633 become(reject(reason));
635 deferred.notify = function (progress) {
636 if (resolvedPromise) {
640 array_reduce(progressListeners, function (undefined, progressListener) {
641 Q.nextTick(function () {
642 progressListener(progress);
651 * Creates a Node-style callback that will resolve or reject the deferred
653 * @returns a nodeback
655 defer.prototype.makeNodeResolver = function () {
657 return function (error, value) {
660 } else if (arguments.length > 2) {
661 self.resolve(array_slice(arguments, 1));
669 * @param resolver {Function} a function that returns nothing and accepts
670 * the resolve, reject, and notify functions for a deferred.
671 * @returns a promise that may be resolved with the given resolve and reject
672 * functions, or rejected by a thrown exception in resolver
674 Q.Promise = promise; // ES6
676 function promise(resolver) {
677 if (typeof resolver !== "function") {
678 throw new TypeError("resolver must be a function.");
680 var deferred = defer();
682 resolver(deferred.resolve, deferred.reject, deferred.notify);
684 deferred.reject(reason);
686 return deferred.promise;
689 promise.race = race; // ES6
690 promise.all = all; // ES6
691 promise.reject = reject; // ES6
692 promise.resolve = Q; // ES6
694 // XXX experimental. This method is a way to denote that a local value is
695 // serializable and should be immediately dispatched to a remote upon request,
696 // instead of passing a reference.
697 Q.passByCopy = function (object) {
699 //passByCopies.set(object, true);
703 Promise.prototype.passByCopy = function () {
705 //passByCopies.set(object, true);
710 * If two promises eventually fulfill to the same value, promises that value,
711 * but otherwise rejects.
714 * @returns {Any*} a promise for x and y if they are the same, but a rejection
718 Q.join = function (x, y) {
722 Promise.prototype.join = function (that) {
723 return Q([this, that]).spread(function (x, y) {
725 // TODO: "===" should be Object.is or equiv
728 throw new Error("Can't join: not the same: " + x + " " + y);
734 * Returns a promise for the first of an array of promises to become settled.
735 * @param answers {Array[Any*]} promises to race
736 * @returns {Any*} the first promise to be settled
739 function race(answerPs) {
740 return promise(function (resolve, reject) {
741 // Switch to this once we can assume at least ES5
742 // answerPs.forEach(function (answerP) {
743 // Q(answerP).then(resolve, reject);
745 // Use this in the meantime
746 for (var i = 0, len = answerPs.length; i < len; i++) {
747 Q(answerPs[i]).then(resolve, reject);
752 Promise.prototype.race = function () {
753 return this.then(Q.race);
757 * Constructs a Promise with a promise descriptor object and optional fallback
758 * function. The descriptor contains methods like when(rejected), get(name),
759 * set(name, value), post(name, args), and delete(name), which all
760 * return either a value, a promise for a value, or a rejection. The fallback
761 * accepts the operation name, a resolver, and any further arguments that would
762 * have been forwarded to the appropriate method above had a method been
763 * provided with the proper name. The API makes no guarantees about the nature
764 * of the returned object, apart from that it is usable whereever promises are
767 Q.makePromise = Promise;
768 function Promise(descriptor, fallback, inspect) {
769 if (fallback === void 0) {
770 fallback = function (op) {
771 return reject(new Error(
772 "Promise does not support operation: " + op
776 if (inspect === void 0) {
777 inspect = function () {
778 return {state: "unknown"};
782 var promise = object_create(Promise.prototype);
784 promise.promiseDispatch = function (resolve, op, args) {
787 if (descriptor[op]) {
788 result = descriptor[op].apply(promise, args);
790 result = fallback.call(promise, op, args);
792 } catch (exception) {
793 result = reject(exception);
800 promise.inspect = inspect;
802 // XXX deprecated `valueOf` and `exception` support
804 var inspected = inspect();
805 if (inspected.state === "rejected") {
806 promise.exception = inspected.reason;
809 promise.valueOf = function () {
810 var inspected = inspect();
811 if (inspected.state === "pending" ||
812 inspected.state === "rejected") {
815 return inspected.value;
822 Promise.prototype.toString = function () {
823 return "[object Promise]";
826 Promise.prototype.then = function (fulfilled, rejected, progressed) {
828 var deferred = defer();
829 var done = false; // ensure the untrusted promise makes at most a
830 // single call to one of the callbacks
832 function _fulfilled(value) {
834 return typeof fulfilled === "function" ? fulfilled(value) : value;
835 } catch (exception) {
836 return reject(exception);
840 function _rejected(exception) {
841 if (typeof rejected === "function") {
842 makeStackTraceLong(exception, self);
844 return rejected(exception);
845 } catch (newException) {
846 return reject(newException);
849 return reject(exception);
852 function _progressed(value) {
853 return typeof progressed === "function" ? progressed(value) : value;
856 Q.nextTick(function () {
857 self.promiseDispatch(function (value) {
863 deferred.resolve(_fulfilled(value));
864 }, "when", [function (exception) {
870 deferred.resolve(_rejected(exception));
874 // Progress propagator need to be attached in the current tick.
875 self.promiseDispatch(void 0, "when", [void 0, function (value) {
879 newValue = _progressed(value);
890 deferred.notify(newValue);
894 return deferred.promise;
897 Q.tap = function (promise, callback) {
898 return Q(promise).tap(callback);
902 * Works almost like "finally", but not called for rejections.
903 * Original resolution value is passed through callback unaffected.
904 * Callback may return a promise that will be awaited for.
905 * @param {Function} callback
906 * @returns {Q.Promise}
913 Promise.prototype.tap = function (callback) {
914 callback = Q(callback);
916 return this.then(function (value) {
917 return callback.fcall(value).thenResolve(value);
922 * Registers an observer on a promise.
926 * 1. that fulfilled and rejected will be called only once.
927 * 2. that either the fulfilled callback or the rejected callback will be
928 * called, but not both.
929 * 3. that fulfilled and rejected will not be called in this turn.
931 * @param value promise or immediate reference to observe
932 * @param fulfilled function to be called with the fulfilled value
933 * @param rejected function to be called with the rejection exception
934 * @param progressed function to be called on any progress notifications
935 * @return promise for the return value from the invoked callback
938 function when(value, fulfilled, rejected, progressed) {
939 return Q(value).then(fulfilled, rejected, progressed);
942 Promise.prototype.thenResolve = function (value) {
943 return this.then(function () { return value; });
946 Q.thenResolve = function (promise, value) {
947 return Q(promise).thenResolve(value);
950 Promise.prototype.thenReject = function (reason) {
951 return this.then(function () { throw reason; });
954 Q.thenReject = function (promise, reason) {
955 return Q(promise).thenReject(reason);
959 * If an object is not a promise, it is as "near" as possible.
960 * If a promise is rejected, it is as "near" as possible too.
961 * If it’s a fulfilled promise, the fulfillment value is nearer.
962 * If it’s a deferred promise and the deferred has been resolved, the
963 * resolution is "nearer".
965 * @returns most resolved (nearest) form of the object
968 // XXX should we re-do this?
970 function nearer(value) {
971 if (isPromise(value)) {
972 var inspected = value.inspect();
973 if (inspected.state === "fulfilled") {
974 return inspected.value;
981 * @returns whether the given object is a promise.
982 * Otherwise it is a fulfilled value.
984 Q.isPromise = isPromise;
985 function isPromise(object) {
986 return object instanceof Promise;
989 Q.isPromiseAlike = isPromiseAlike;
990 function isPromiseAlike(object) {
991 return isObject(object) && typeof object.then === "function";
995 * @returns whether the given object is a pending promise, meaning not
996 * fulfilled or rejected.
998 Q.isPending = isPending;
999 function isPending(object) {
1000 return isPromise(object) && object.inspect().state === "pending";
1003 Promise.prototype.isPending = function () {
1004 return this.inspect().state === "pending";
1008 * @returns whether the given object is a value or fulfilled
1011 Q.isFulfilled = isFulfilled;
1012 function isFulfilled(object) {
1013 return !isPromise(object) || object.inspect().state === "fulfilled";
1016 Promise.prototype.isFulfilled = function () {
1017 return this.inspect().state === "fulfilled";
1021 * @returns whether the given object is a rejected promise.
1023 Q.isRejected = isRejected;
1024 function isRejected(object) {
1025 return isPromise(object) && object.inspect().state === "rejected";
1028 Promise.prototype.isRejected = function () {
1029 return this.inspect().state === "rejected";
1032 //// BEGIN UNHANDLED REJECTION TRACKING
1034 // This promise library consumes exceptions thrown in handlers so they can be
1035 // handled by a subsequent promise. The exceptions get added to this array when
1036 // they are created, and removed when they are handled. Note that in ES6 or
1037 // shimmed environments, this would naturally be a `Set`.
1038 var unhandledReasons = [];
1039 var unhandledRejections = [];
1040 var reportedUnhandledRejections = [];
1041 var trackUnhandledRejections = true;
1043 function resetUnhandledRejections() {
1044 unhandledReasons.length = 0;
1045 unhandledRejections.length = 0;
1047 if (!trackUnhandledRejections) {
1048 trackUnhandledRejections = true;
1052 function trackRejection(promise, reason) {
1053 if (!trackUnhandledRejections) {
1056 if (typeof process === "object" && typeof process.emit === "function") {
1057 Q.nextTick.runAfter(function () {
1058 if (array_indexOf(unhandledRejections, promise) !== -1) {
1059 process.emit("unhandledRejection", reason, promise);
1060 reportedUnhandledRejections.push(promise);
1065 unhandledRejections.push(promise);
1066 if (reason && typeof reason.stack !== "undefined") {
1067 unhandledReasons.push(reason.stack);
1069 unhandledReasons.push("(no stack) " + reason);
1073 function untrackRejection(promise) {
1074 if (!trackUnhandledRejections) {
1078 var at = array_indexOf(unhandledRejections, promise);
1080 if (typeof process === "object" && typeof process.emit === "function") {
1081 Q.nextTick.runAfter(function () {
1082 var atReport = array_indexOf(reportedUnhandledRejections, promise);
1083 if (atReport !== -1) {
1084 process.emit("rejectionHandled", unhandledReasons[at], promise);
1085 reportedUnhandledRejections.splice(atReport, 1);
1089 unhandledRejections.splice(at, 1);
1090 unhandledReasons.splice(at, 1);
1094 Q.resetUnhandledRejections = resetUnhandledRejections;
1096 Q.getUnhandledReasons = function () {
1097 // Make a copy so that consumers can't interfere with our internal state.
1098 return unhandledReasons.slice();
1101 Q.stopUnhandledRejectionTracking = function () {
1102 resetUnhandledRejections();
1103 trackUnhandledRejections = false;
1106 resetUnhandledRejections();
1108 //// END UNHANDLED REJECTION TRACKING
1111 * Constructs a rejected promise.
1112 * @param reason value describing the failure
1115 function reject(reason) {
1116 var rejection = Promise({
1117 "when": function (rejected) {
1118 // note that the error has been handled
1120 untrackRejection(this);
1122 return rejected ? rejected(reason) : this;
1124 }, function fallback() {
1126 }, function inspect() {
1127 return { state: "rejected", reason: reason };
1130 // Note that the reason has not been handled.
1131 trackRejection(rejection, reason);
1137 * Constructs a fulfilled promise for an immediate reference.
1138 * @param value immediate reference
1140 Q.fulfill = fulfill;
1141 function fulfill(value) {
1143 "when": function () {
1146 "get": function (name) {
1149 "set": function (name, rhs) {
1152 "delete": function (name) {
1155 "post": function (name, args) {
1156 // Mark Miller proposes that post with no name should apply a
1157 // promised function.
1158 if (name === null || name === void 0) {
1159 return value.apply(void 0, args);
1161 return value[name].apply(value, args);
1164 "apply": function (thisp, args) {
1165 return value.apply(thisp, args);
1167 "keys": function () {
1168 return object_keys(value);
1170 }, void 0, function inspect() {
1171 return { state: "fulfilled", value: value };
1176 * Converts thenables to Q promises.
1177 * @param promise thenable promise
1178 * @returns a Q promise
1180 function coerce(promise) {
1181 var deferred = defer();
1182 Q.nextTick(function () {
1184 promise.then(deferred.resolve, deferred.reject, deferred.notify);
1185 } catch (exception) {
1186 deferred.reject(exception);
1189 return deferred.promise;
1193 * Annotates an object such that it will never be
1194 * transferred away from this process over any promise
1195 * communication channel.
1197 * @returns promise a wrapping of that object that
1198 * additionally responds to the "isDef" message
1199 * without a rejection.
1202 function master(object) {
1204 "isDef": function () {}
1205 }, function fallback(op, args) {
1206 return dispatch(object, op, args);
1208 return Q(object).inspect();
1213 * Spreads the values of a promised array of arguments into the
1214 * fulfillment callback.
1215 * @param fulfilled callback that receives variadic arguments from the
1217 * @param rejected callback that receives the exception if the promise
1219 * @returns a promise for the return value or thrown exception of
1223 function spread(value, fulfilled, rejected) {
1224 return Q(value).spread(fulfilled, rejected);
1227 Promise.prototype.spread = function (fulfilled, rejected) {
1228 return this.all().then(function (array) {
1229 return fulfilled.apply(void 0, array);
1234 * The async function is a decorator for generator functions, turning
1235 * them into asynchronous generators. Although generators are only part
1236 * of the newest ECMAScript 6 drafts, this code does not cause syntax
1237 * errors in older engines. This code should continue to work and will
1238 * in fact improve over time as the language improves.
1240 * ES6 generators are currently part of V8 version 3.19 with the
1241 * --harmony-generators runtime flag enabled. SpiderMonkey has had them
1242 * for longer, but under an older Python-inspired form. This function
1243 * works on both kinds of generators.
1245 * Decorates a generator function such that:
1246 * - it may yield promises
1247 * - execution will continue when that promise is fulfilled
1248 * - the value of the yield expression will be the fulfilled value
1249 * - it returns a promise for the return value (when the generator
1251 * - the decorated function returns a promise for the return value
1252 * of the generator or the first rejected promise among those
1254 * - if an error is thrown in the generator, it propagates through
1255 * every following yield until it is caught, or until it escapes
1256 * the generator function altogether, and is translated into a
1257 * rejection for the promise returned by the decorated generator.
1260 function async(makeGenerator) {
1261 return function () {
1262 // when verb is "send", arg is a value
1263 // when verb is "throw", arg is an exception
1264 function continuer(verb, arg) {
1267 // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
1268 // engine that has a deployed base of browsers that support generators.
1269 // However, SM's generators use the Python-inspired semantics of
1270 // outdated ES6 drafts. We would like to support ES6, but we'd also
1271 // like to make it possible to use generators in deployed browsers, so
1272 // we also support Python-style generators. At some point we can remove
1275 if (typeof StopIteration === "undefined") {
1278 result = generator[verb](arg);
1279 } catch (exception) {
1280 return reject(exception);
1283 return Q(result.value);
1285 return when(result.value, callback, errback);
1288 // SpiderMonkey Generators
1289 // FIXME: Remove this case when SM does ES6 generators.
1291 result = generator[verb](arg);
1292 } catch (exception) {
1293 if (isStopIteration(exception)) {
1294 return Q(exception.value);
1296 return reject(exception);
1299 return when(result, callback, errback);
1302 var generator = makeGenerator.apply(this, arguments);
1303 var callback = continuer.bind(continuer, "next");
1304 var errback = continuer.bind(continuer, "throw");
1310 * The spawn function is a small wrapper around async that immediately
1311 * calls the generator and also ends the promise chain, so that any
1312 * unhandled errors are thrown instead of forwarded to the error
1313 * handler. This is useful because it's extremely common to run
1314 * generators at the top-level to work with libraries.
1317 function spawn(makeGenerator) {
1318 Q.done(Q.async(makeGenerator)());
1321 // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
1323 * Throws a ReturnValue exception to stop an asynchronous generator.
1325 * This interface is a stop-gap measure to support generator return
1326 * values in older Firefox/SpiderMonkey. In browsers that support ES6
1327 * generators like Chromium 29, just use "return" in your generator
1330 * @param value the return value for the surrounding generator
1331 * @throws ReturnValue exception with the value.
1334 * Q.async(function* () {
1335 * var foo = yield getFooPromise();
1336 * var bar = yield getBarPromise();
1339 * // Older SpiderMonkey style
1340 * Q.async(function () {
1341 * var foo = yield getFooPromise();
1342 * var bar = yield getBarPromise();
1343 * Q.return(foo + bar);
1346 Q["return"] = _return;
1347 function _return(value) {
1348 throw new QReturnValue(value);
1352 * The promised function decorator ensures that any promise arguments
1353 * are settled and passed as values (`this` is also settled and passed
1354 * as a value). It will also ensure that the result of a function is
1358 * var add = Q.promised(function (a, b) {
1363 * @param {function} callback The function to decorate
1364 * @returns {function} a function that has been decorated.
1366 Q.promised = promised;
1367 function promised(callback) {
1368 return function () {
1369 return spread([this, all(arguments)], function (self, args) {
1370 return callback.apply(self, args);
1376 * sends a message to a value in a future turn
1377 * @param object* the recipient
1378 * @param op the name of the message operation, e.g., "when",
1379 * @param args further arguments to be forwarded to the operation
1380 * @returns result {Promise} a promise for the result of the operation
1382 Q.dispatch = dispatch;
1383 function dispatch(object, op, args) {
1384 return Q(object).dispatch(op, args);
1387 Promise.prototype.dispatch = function (op, args) {
1389 var deferred = defer();
1390 Q.nextTick(function () {
1391 self.promiseDispatch(deferred.resolve, op, args);
1393 return deferred.promise;
1397 * Gets the value of a property in a future turn.
1398 * @param object promise or immediate reference for target object
1399 * @param name name of property to get
1400 * @return promise for the property value
1402 Q.get = function (object, key) {
1403 return Q(object).dispatch("get", [key]);
1406 Promise.prototype.get = function (key) {
1407 return this.dispatch("get", [key]);
1411 * Sets the value of a property in a future turn.
1412 * @param object promise or immediate reference for object object
1413 * @param name name of property to set
1414 * @param value new value of property
1415 * @return promise for the return value
1417 Q.set = function (object, key, value) {
1418 return Q(object).dispatch("set", [key, value]);
1421 Promise.prototype.set = function (key, value) {
1422 return this.dispatch("set", [key, value]);
1426 * Deletes a property in a future turn.
1427 * @param object promise or immediate reference for target object
1428 * @param name name of property to delete
1429 * @return promise for the return value
1431 Q.del = // XXX legacy
1432 Q["delete"] = function (object, key) {
1433 return Q(object).dispatch("delete", [key]);
1436 Promise.prototype.del = // XXX legacy
1437 Promise.prototype["delete"] = function (key) {
1438 return this.dispatch("delete", [key]);
1442 * Invokes a method in a future turn.
1443 * @param object promise or immediate reference for target object
1444 * @param name name of method to invoke
1445 * @param value a value to post, typically an array of
1446 * invocation arguments for promises that
1447 * are ultimately backed with `resolve` values,
1448 * as opposed to those backed with URLs
1449 * wherein the posted value can be any
1450 * JSON serializable object.
1451 * @return promise for the return value
1453 // bound locally because it is used by other methods
1454 Q.mapply = // XXX As proposed by "Redsandro"
1455 Q.post = function (object, name, args) {
1456 return Q(object).dispatch("post", [name, args]);
1459 Promise.prototype.mapply = // XXX As proposed by "Redsandro"
1460 Promise.prototype.post = function (name, args) {
1461 return this.dispatch("post", [name, args]);
1465 * Invokes a method in a future turn.
1466 * @param object promise or immediate reference for target object
1467 * @param name name of method to invoke
1468 * @param ...args array of invocation arguments
1469 * @return promise for the return value
1471 Q.send = // XXX Mark Miller's proposed parlance
1472 Q.mcall = // XXX As proposed by "Redsandro"
1473 Q.invoke = function (object, name /*...args*/) {
1474 return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
1477 Promise.prototype.send = // XXX Mark Miller's proposed parlance
1478 Promise.prototype.mcall = // XXX As proposed by "Redsandro"
1479 Promise.prototype.invoke = function (name /*...args*/) {
1480 return this.dispatch("post", [name, array_slice(arguments, 1)]);
1484 * Applies the promised function in a future turn.
1485 * @param object promise or immediate reference for target function
1486 * @param args array of application arguments
1488 Q.fapply = function (object, args) {
1489 return Q(object).dispatch("apply", [void 0, args]);
1492 Promise.prototype.fapply = function (args) {
1493 return this.dispatch("apply", [void 0, args]);
1497 * Calls the promised function in a future turn.
1498 * @param object promise or immediate reference for target function
1499 * @param ...args array of application arguments
1502 Q.fcall = function (object /* ...args*/) {
1503 return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
1506 Promise.prototype.fcall = function (/*...args*/) {
1507 return this.dispatch("apply", [void 0, array_slice(arguments)]);
1511 * Binds the promised function, transforming return values into a fulfilled
1512 * promise and thrown errors into a rejected one.
1513 * @param object promise or immediate reference for target function
1514 * @param ...args array of application arguments
1516 Q.fbind = function (object /*...args*/) {
1517 var promise = Q(object);
1518 var args = array_slice(arguments, 1);
1519 return function fbound() {
1520 return promise.dispatch("apply", [
1522 args.concat(array_slice(arguments))
1526 Promise.prototype.fbind = function (/*...args*/) {
1528 var args = array_slice(arguments);
1529 return function fbound() {
1530 return promise.dispatch("apply", [
1532 args.concat(array_slice(arguments))
1538 * Requests the names of the owned properties of a promised
1539 * object in a future turn.
1540 * @param object promise or immediate reference for target object
1541 * @return promise for the keys of the eventually settled object
1543 Q.keys = function (object) {
1544 return Q(object).dispatch("keys", []);
1547 Promise.prototype.keys = function () {
1548 return this.dispatch("keys", []);
1552 * Turns an array of promises into a promise for an array. If any of
1553 * the promises gets rejected, the whole array is rejected immediately.
1554 * @param {Array*} an array (or promise for an array) of values (or
1555 * promises for values)
1556 * @returns a promise for an array of the corresponding values
1559 // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
1561 function all(promises) {
1562 return when(promises, function (promises) {
1563 var pendingCount = 0;
1564 var deferred = defer();
1565 array_reduce(promises, function (undefined, promise, index) {
1568 isPromise(promise) &&
1569 (snapshot = promise.inspect()).state === "fulfilled"
1571 promises[index] = snapshot.value;
1577 promises[index] = value;
1578 if (--pendingCount === 0) {
1579 deferred.resolve(promises);
1583 function (progress) {
1584 deferred.notify({ index: index, value: progress });
1589 if (pendingCount === 0) {
1590 deferred.resolve(promises);
1592 return deferred.promise;
1596 Promise.prototype.all = function () {
1601 * Returns the first resolved promise of an array. Prior rejected promises are
1602 * ignored. Rejects only if all promises are rejected.
1603 * @param {Array*} an array containing values or promises for values
1604 * @returns a promise fulfilled with the value of the first resolved promise,
1605 * or a rejected promise if all promises are rejected.
1609 function any(promises) {
1610 if (promises.length === 0) {
1614 var deferred = Q.defer();
1615 var pendingCount = 0;
1616 array_reduce(promises, function (prev, current, index) {
1617 var promise = promises[index];
1621 when(promise, onFulfilled, onRejected, onProgress);
1622 function onFulfilled(result) {
1623 deferred.resolve(result);
1625 function onRejected() {
1627 if (pendingCount === 0) {
1628 deferred.reject(new Error(
1629 "Can't get fulfillment value from any promise, all " +
1630 "promises were rejected."
1634 function onProgress(progress) {
1642 return deferred.promise;
1645 Promise.prototype.any = function () {
1650 * Waits for all promises to be settled, either fulfilled or
1651 * rejected. This is distinct from `all` since that would stop
1652 * waiting at the first rejection. The promise returned by
1653 * `allResolved` will never be rejected.
1654 * @param promises a promise for an array (or an array) of promises
1656 * @return a promise for an array of promises
1658 Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
1659 function allResolved(promises) {
1660 return when(promises, function (promises) {
1661 promises = array_map(promises, Q);
1662 return when(all(array_map(promises, function (promise) {
1663 return when(promise, noop, noop);
1670 Promise.prototype.allResolved = function () {
1671 return allResolved(this);
1675 * @see Promise#allSettled
1677 Q.allSettled = allSettled;
1678 function allSettled(promises) {
1679 return Q(promises).allSettled();
1683 * Turns an array of promises into a promise for an array of their states (as
1684 * returned by `inspect`) when they have all settled.
1685 * @param {Array[Any*]} values an array (or promise for an array) of values (or
1686 * promises for values)
1687 * @returns {Array[State]} an array of states for the respective values.
1689 Promise.prototype.allSettled = function () {
1690 return this.then(function (promises) {
1691 return all(array_map(promises, function (promise) {
1692 promise = Q(promise);
1693 function regardless() {
1694 return promise.inspect();
1696 return promise.then(regardless, regardless);
1702 * Captures the failure of a promise, giving an oportunity to recover
1703 * with a callback. If the given promise is fulfilled, the returned
1704 * promise is fulfilled.
1705 * @param {Any*} promise for something
1706 * @param {Function} callback to fulfill the returned promise if the
1707 * given promise is rejected
1708 * @returns a promise for the return value of the callback
1710 Q.fail = // XXX legacy
1711 Q["catch"] = function (object, rejected) {
1712 return Q(object).then(void 0, rejected);
1715 Promise.prototype.fail = // XXX legacy
1716 Promise.prototype["catch"] = function (rejected) {
1717 return this.then(void 0, rejected);
1721 * Attaches a listener that can respond to progress notifications from a
1722 * promise's originating deferred. This listener receives the exact arguments
1723 * passed to ``deferred.notify``.
1724 * @param {Any*} promise for something
1725 * @param {Function} callback to receive any progress notifications
1726 * @returns the given promise, unchanged
1728 Q.progress = progress;
1729 function progress(object, progressed) {
1730 return Q(object).then(void 0, void 0, progressed);
1733 Promise.prototype.progress = function (progressed) {
1734 return this.then(void 0, void 0, progressed);
1738 * Provides an opportunity to observe the settling of a promise,
1739 * regardless of whether the promise is fulfilled or rejected. Forwards
1740 * the resolution to the returned promise when the callback is done.
1741 * The callback can return a promise to defer completion.
1742 * @param {Any*} promise
1743 * @param {Function} callback to observe the resolution of the given
1744 * promise, takes no arguments.
1745 * @returns a promise for the resolution of the given promise when
1748 Q.fin = // XXX legacy
1749 Q["finally"] = function (object, callback) {
1750 return Q(object)["finally"](callback);
1753 Promise.prototype.fin = // XXX legacy
1754 Promise.prototype["finally"] = function (callback) {
1755 callback = Q(callback);
1756 return this.then(function (value) {
1757 return callback.fcall().then(function () {
1760 }, function (reason) {
1761 // TODO attempt to recycle the rejection with "this".
1762 return callback.fcall().then(function () {
1769 * Terminates a chain of promises, forcing rejections to be
1770 * thrown as exceptions.
1771 * @param {Any*} promise at the end of a chain of promises
1774 Q.done = function (object, fulfilled, rejected, progress) {
1775 return Q(object).done(fulfilled, rejected, progress);
1778 Promise.prototype.done = function (fulfilled, rejected, progress) {
1779 var onUnhandledError = function (error) {
1780 // forward to a future turn so that ``when``
1781 // does not catch it and turn it into a rejection.
1782 Q.nextTick(function () {
1783 makeStackTraceLong(error, promise);
1792 // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
1793 var promise = fulfilled || rejected || progress ?
1794 this.then(fulfilled, rejected, progress) :
1797 if (typeof process === "object" && process && process.domain) {
1798 onUnhandledError = process.domain.bind(onUnhandledError);
1801 promise.then(void 0, onUnhandledError);
1805 * Causes a promise to be rejected if it does not get fulfilled before
1806 * some milliseconds time out.
1807 * @param {Any*} promise
1808 * @param {Number} milliseconds timeout
1809 * @param {Any*} custom error message or Error object (optional)
1810 * @returns a promise for the resolution of the given promise if it is
1811 * fulfilled before the timeout, otherwise rejected.
1813 Q.timeout = function (object, ms, error) {
1814 return Q(object).timeout(ms, error);
1817 Promise.prototype.timeout = function (ms, error) {
1818 var deferred = defer();
1819 var timeoutId = setTimeout(function () {
1820 if (!error || "string" === typeof error) {
1821 error = new Error(error || "Timed out after " + ms + " ms");
1822 error.code = "ETIMEDOUT";
1824 deferred.reject(error);
1827 this.then(function (value) {
1828 clearTimeout(timeoutId);
1829 deferred.resolve(value);
1830 }, function (exception) {
1831 clearTimeout(timeoutId);
1832 deferred.reject(exception);
1833 }, deferred.notify);
1835 return deferred.promise;
1839 * Returns a promise for the given value (or promised value), some
1840 * milliseconds after it resolved. Passes rejections immediately.
1841 * @param {Any*} promise
1842 * @param {Number} milliseconds
1843 * @returns a promise for the resolution of the given promise after milliseconds
1844 * time has elapsed since the resolution of the given promise.
1845 * If the given promise rejects, that is passed immediately.
1847 Q.delay = function (object, timeout) {
1848 if (timeout === void 0) {
1852 return Q(object).delay(timeout);
1855 Promise.prototype.delay = function (timeout) {
1856 return this.then(function (value) {
1857 var deferred = defer();
1858 setTimeout(function () {
1859 deferred.resolve(value);
1861 return deferred.promise;
1866 * Passes a continuation to a Node function, which is called with the given
1867 * arguments provided as an array, and returns a promise.
1869 * Q.nfapply(FS.readFile, [__filename])
1870 * .then(function (content) {
1874 Q.nfapply = function (callback, args) {
1875 return Q(callback).nfapply(args);
1878 Promise.prototype.nfapply = function (args) {
1879 var deferred = defer();
1880 var nodeArgs = array_slice(args);
1881 nodeArgs.push(deferred.makeNodeResolver());
1882 this.fapply(nodeArgs).fail(deferred.reject);
1883 return deferred.promise;
1887 * Passes a continuation to a Node function, which is called with the given
1888 * arguments provided individually, and returns a promise.
1890 * Q.nfcall(FS.readFile, __filename)
1891 * .then(function (content) {
1895 Q.nfcall = function (callback /*...args*/) {
1896 var args = array_slice(arguments, 1);
1897 return Q(callback).nfapply(args);
1900 Promise.prototype.nfcall = function (/*...args*/) {
1901 var nodeArgs = array_slice(arguments);
1902 var deferred = defer();
1903 nodeArgs.push(deferred.makeNodeResolver());
1904 this.fapply(nodeArgs).fail(deferred.reject);
1905 return deferred.promise;
1909 * Wraps a NodeJS continuation passing function and returns an equivalent
1910 * version that returns a promise.
1912 * Q.nfbind(FS.readFile, __filename)("utf-8")
1913 * .then(console.log)
1917 Q.denodeify = function (callback /*...args*/) {
1918 var baseArgs = array_slice(arguments, 1);
1919 return function () {
1920 var nodeArgs = baseArgs.concat(array_slice(arguments));
1921 var deferred = defer();
1922 nodeArgs.push(deferred.makeNodeResolver());
1923 Q(callback).fapply(nodeArgs).fail(deferred.reject);
1924 return deferred.promise;
1928 Promise.prototype.nfbind =
1929 Promise.prototype.denodeify = function (/*...args*/) {
1930 var args = array_slice(arguments);
1932 return Q.denodeify.apply(void 0, args);
1935 Q.nbind = function (callback, thisp /*...args*/) {
1936 var baseArgs = array_slice(arguments, 2);
1937 return function () {
1938 var nodeArgs = baseArgs.concat(array_slice(arguments));
1939 var deferred = defer();
1940 nodeArgs.push(deferred.makeNodeResolver());
1942 return callback.apply(thisp, arguments);
1944 Q(bound).fapply(nodeArgs).fail(deferred.reject);
1945 return deferred.promise;
1949 Promise.prototype.nbind = function (/*thisp, ...args*/) {
1950 var args = array_slice(arguments, 0);
1952 return Q.nbind.apply(void 0, args);
1956 * Calls a method of a Node-style object that accepts a Node-style
1957 * callback with a given array of arguments, plus a provided callback.
1958 * @param object an object that has the named method
1959 * @param {String} name name of the method of object
1960 * @param {Array} args arguments to pass to the method; the callback
1961 * will be provided by Q and appended to these arguments.
1962 * @returns a promise for the value or error
1964 Q.nmapply = // XXX As proposed by "Redsandro"
1965 Q.npost = function (object, name, args) {
1966 return Q(object).npost(name, args);
1969 Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
1970 Promise.prototype.npost = function (name, args) {
1971 var nodeArgs = array_slice(args || []);
1972 var deferred = defer();
1973 nodeArgs.push(deferred.makeNodeResolver());
1974 this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
1975 return deferred.promise;
1979 * Calls a method of a Node-style object that accepts a Node-style
1980 * callback, forwarding the given variadic arguments, plus a provided
1981 * callback argument.
1982 * @param object an object that has the named method
1983 * @param {String} name name of the method of object
1984 * @param ...args arguments to pass to the method; the callback will
1985 * be provided by Q and appended to these arguments.
1986 * @returns a promise for the value or error
1988 Q.nsend = // XXX Based on Mark Miller's proposed "send"
1989 Q.nmcall = // XXX Based on "Redsandro's" proposal
1990 Q.ninvoke = function (object, name /*...args*/) {
1991 var nodeArgs = array_slice(arguments, 2);
1992 var deferred = defer();
1993 nodeArgs.push(deferred.makeNodeResolver());
1994 Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
1995 return deferred.promise;
1998 Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
1999 Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
2000 Promise.prototype.ninvoke = function (name /*...args*/) {
2001 var nodeArgs = array_slice(arguments, 1);
2002 var deferred = defer();
2003 nodeArgs.push(deferred.makeNodeResolver());
2004 this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
2005 return deferred.promise;
2009 * If a function would like to support both Node continuation-passing-style and
2010 * promise-returning-style, it can end its internal promise chain with
2011 * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
2012 * elects to use a nodeback, the result will be sent there. If they do not
2013 * pass a nodeback, they will receive the result promise.
2014 * @param object a result (or a promise for a result)
2015 * @param {Function} nodeback a Node.js-style callback
2016 * @returns either the promise or nothing
2018 Q.nodeify = nodeify;
2019 function nodeify(object, nodeback) {
2020 return Q(object).nodeify(nodeback);
2023 Promise.prototype.nodeify = function (nodeback) {
2025 this.then(function (value) {
2026 Q.nextTick(function () {
2027 nodeback(null, value);
2029 }, function (error) {
2030 Q.nextTick(function () {
2039 Q.noConflict = function() {
2040 throw new Error("Q.noConflict only works when Q is used as a global");
2043 // All code before this point will be filtered from stack traces.
2044 var qEndingLine = captureLine();