// vim:ts=4:sts=4:sw=4:1/*!2*3* Copyright 2009-2012 Kris Kowal under the terms of the MIT4* license found at http://github.com/kriskowal/q/raw/master/LICENSE5*6* With parts by Tyler Close7* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found8* at http://www.opensource.org/licenses/mit-license.html9* Forked at ref_send.js version: 2009-05-1110*11* With parts by Mark Miller12* Copyright (C) 2011 Google Inc.13*14* Licensed under the Apache License, Version 2.0 (the "License");15* you may not use this file except in compliance with the License.16* You may obtain a copy of the License at17*18* http://www.apache.org/licenses/LICENSE-2.019*20* Unless required by applicable law or agreed to in writing, software21* distributed under the License is distributed on an "AS IS" BASIS,22* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.23* See the License for the specific language governing permissions and24* limitations under the License.25*26*/2728(function (definition) {29// Turn off strict mode for this function so we can assign to global.Q30/* jshint strict: false */3132// This file will function properly as a <script> tag, or a module33// using CommonJS and NodeJS or RequireJS module formats. In34// Common/Node/RequireJS, the module exports the Q API and when35// executed as a simple <script>, it creates a Q global instead.3637// Montage Require38if (typeof bootstrap === "function") {39bootstrap("promise", definition);4041// CommonJS42} else if (typeof exports === "object") {43module.exports = definition();4445// RequireJS46} else if (typeof define === "function" && define.amd) {47define(definition);4849// SES (Secure EcmaScript)50} else if (typeof ses !== "undefined") {51if (!ses.ok()) {52return;53} else {54ses.makeQ = definition;55}5657// <script>58} else {59Q = definition();60}6162})(function () {63"use strict";6465var hasStacks = false;66try {67throw new Error();68} catch (e) {69hasStacks = !!e.stack;70}7172// All code after this point will be filtered from stack traces reported73// by Q.74var qStartingLine = captureLine();75var qFileName;7677// shims7879// used for fallback in "allResolved"80var noop = function () {};8182// Use the fastest possible means to execute a task in a future turn83// of the event loop.84var nextTick =(function () {85// linked list of tasks (single, with head node)86var head = {task: void 0, next: null};87var tail = head;88var flushing = false;89var requestTick = void 0;90var isNodeJS = false;9192function flush() {93/* jshint loopfunc: true */9495while (head.next) {96head = head.next;97var task = head.task;98head.task = void 0;99var domain = head.domain;100101if (domain) {102head.domain = void 0;103domain.enter();104}105106try {107task();108109} catch (e) {110if (isNodeJS) {111// In node, uncaught exceptions are considered fatal errors.112// Re-throw them synchronously to interrupt flushing!113114// Ensure continuation if the uncaught exception is suppressed115// listening "uncaughtException" events (as domains does).116// Continue in next event to avoid tick recursion.117if (domain) {118domain.exit();119}120setTimeout(flush, 0);121if (domain) {122domain.enter();123}124125throw e;126127} else {128// In browsers, uncaught exceptions are not fatal.129// Re-throw them asynchronously to avoid slow-downs.130setTimeout(function() {131throw e;132}, 0);133}134}135136if (domain) {137domain.exit();138}139}140141flushing = false;142}143144nextTick = function (task) {145tail = tail.next = {146task: task,147domain: isNodeJS && process.domain,148next: null149};150151if (!flushing) {152flushing = true;153requestTick();154}155};156157if (typeof process !== "undefined" && process.nextTick) {158// Node.js before 0.9. Note that some fake-Node environments, like the159// Mocha test runner, introduce a `process` global without a `nextTick`.160isNodeJS = true;161162requestTick = function () {163process.nextTick(flush);164};165166} else if (typeof setImmediate === "function") {167// In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate168if (typeof window !== "undefined") {169requestTick = setImmediate.bind(window, flush);170} else {171requestTick = function () {172setImmediate(flush);173};174}175176} else if (typeof MessageChannel !== "undefined") {177// modern browsers178// http://www.nonblocking.io/2011/06/windownexttick.html179var channel = new MessageChannel();180// At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create181// working message ports the first time a page loads.182channel.port1.onmessage = function () {183requestTick = requestPortTick;184channel.port1.onmessage = flush;185flush();186};187var requestPortTick = function () {188// Opera requires us to provide a message payload, regardless of189// whether we use it.190channel.port2.postMessage(0);191};192requestTick = function () {193setTimeout(flush, 0);194requestPortTick();195};196197} else {198// old browsers199requestTick = function () {200setTimeout(flush, 0);201};202}203204return nextTick;205})();206207// Attempt to make generics safe in the face of downstream208// modifications.209// There is no situation where this is necessary.210// If you need a security guarantee, these primordials need to be211// deeply frozen anyway, and if you don’t need a security guarantee,212// this is just plain paranoid.213// However, this does have the nice side-effect of reducing the size214// of the code by reducing x.call() to merely x(), eliminating many215// hard-to-minify characters.216// See Mark Miller’s explanation of what this does.217// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming218var call = Function.call;219function uncurryThis(f) {220return function () {221return call.apply(f, arguments);222};223}224// This is equivalent, but slower:225// uncurryThis = Function_bind.bind(Function_bind.call);226// http://jsperf.com/uncurrythis227228var array_slice = uncurryThis(Array.prototype.slice);229230var array_reduce = uncurryThis(231Array.prototype.reduce || function (callback, basis) {232var index = 0,233length = this.length;234// concerning the initial value, if one is not provided235if (arguments.length === 1) {236// seek to the first value in the array, accounting237// for the possibility that is is a sparse array238do {239if (index in this) {240basis = this[index++];241break;242}243if (++index >= length) {244throw new TypeError();245}246} while (1);247}248// reduce249for (; index < length; index++) {250// account for the possibility that the array is sparse251if (index in this) {252basis = callback(basis, this[index], index);253}254}255return basis;256}257);258259var array_indexOf = uncurryThis(260Array.prototype.indexOf || function (value) {261// not a very good shim, but good enough for our one use of it262for (var i = 0; i < this.length; i++) {263if (this[i] === value) {264return i;265}266}267return -1;268}269);270271var array_map = uncurryThis(272Array.prototype.map || function (callback, thisp) {273var self = this;274var collect = [];275array_reduce(self, function (undefined, value, index) {276collect.push(callback.call(thisp, value, index, self));277}, void 0);278return collect;279}280);281282var object_create = Object.create || function (prototype) {283function Type() { }284Type.prototype = prototype;285return new Type();286};287288var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);289290var object_keys = Object.keys || function (object) {291var keys = [];292for (var key in object) {293if (object_hasOwnProperty(object, key)) {294keys.push(key);295}296}297return keys;298};299300var object_toString = uncurryThis(Object.prototype.toString);301302function isObject(value) {303return value === Object(value);304}305306// generator related shims307308// FIXME: Remove this function once ES6 generators are in SpiderMonkey.309function isStopIteration(exception) {310return (311object_toString(exception) === "[object StopIteration]" ||312exception instanceof QReturnValue313);314}315316// FIXME: Remove this helper and Q.return once ES6 generators are in317// SpiderMonkey.318var QReturnValue;319if (typeof ReturnValue !== "undefined") {320QReturnValue = ReturnValue;321} else {322QReturnValue = function (value) {323this.value = value;324};325}326327// Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only328// engine that has a deployed base of browsers that support generators.329// However, SM's generators use the Python-inspired semantics of330// outdated ES6 drafts. We would like to support ES6, but we'd also331// like to make it possible to use generators in deployed browsers, so332// we also support Python-style generators. At some point we can remove333// this block.334var hasES6Generators;335try {336/* jshint evil: true, nonew: false */337new Function("(function* (){ yield 1; })");338hasES6Generators = true;339} catch (e) {340hasES6Generators = false;341}342343// long stack traces344345var STACK_JUMP_SEPARATOR = "From previous event:";346347function makeStackTraceLong(error, promise) {348// If possible, transform the error stack trace by removing Node and Q349// cruft, then concatenating with the stack trace of `promise`. See #57.350if (hasStacks &&351promise.stack &&352typeof error === "object" &&353error !== null &&354error.stack &&355error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1356) {357var stacks = [];358for (var p = promise; !!p; p = p.source) {359if (p.stack) {360stacks.unshift(p.stack);361}362}363stacks.unshift(error.stack);364365var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");366error.stack = filterStackString(concatedStacks);367}368}369370function filterStackString(stackString) {371var lines = stackString.split("\n");372var desiredLines = [];373for (var i = 0; i < lines.length; ++i) {374var line = lines[i];375376if (!isInternalFrame(line) && !isNodeFrame(line) && line) {377desiredLines.push(line);378}379}380return desiredLines.join("\n");381}382383function isNodeFrame(stackLine) {384return stackLine.indexOf("(module.js:") !== -1 ||385stackLine.indexOf("(node.js:") !== -1;386}387388function getFileNameAndLineNumber(stackLine) {389// Named functions: "at functionName (filename:lineNumber:columnNumber)"390// In IE10 function name can have spaces ("Anonymous function") O_o391var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);392if (attempt1) {393return [attempt1[1], Number(attempt1[2])];394}395396// Anonymous functions: "at filename:lineNumber:columnNumber"397var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);398if (attempt2) {399return [attempt2[1], Number(attempt2[2])];400}401402// Firefox style: "function@filename:lineNumber or @filename:lineNumber"403var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);404if (attempt3) {405return [attempt3[1], Number(attempt3[2])];406}407}408409function isInternalFrame(stackLine) {410var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);411412if (!fileNameAndLineNumber) {413return false;414}415416var fileName = fileNameAndLineNumber[0];417var lineNumber = fileNameAndLineNumber[1];418419return fileName === qFileName &&420lineNumber >= qStartingLine &&421lineNumber <= qEndingLine;422}423424// discover own file name and line number range for filtering stack425// traces426function captureLine() {427if (!hasStacks) {428return;429}430431try {432throw new Error();433} catch (e) {434var lines = e.stack.split("\n");435var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];436var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);437if (!fileNameAndLineNumber) {438return;439}440441qFileName = fileNameAndLineNumber[0];442return fileNameAndLineNumber[1];443}444}445446function deprecate(callback, name, alternative) {447return function () {448if (typeof console !== "undefined" &&449typeof console.warn === "function") {450console.warn(name + " is deprecated, use " + alternative +451" instead.", new Error("").stack);452}453return callback.apply(callback, arguments);454};455}456457// end of shims458// beginning of real work459460/**461* Constructs a promise for an immediate reference, passes promises through, or462* coerces promises from different systems.463* @param value immediate reference or promise464*/465function Q(value) {466// If the object is already a Promise, return it directly. This enables467// the resolve function to both be used to created references from objects,468// but to tolerably coerce non-promises to promises.469if (isPromise(value)) {470return value;471}472473// assimilate thenables474if (isPromiseAlike(value)) {475return coerce(value);476} else {477return fulfill(value);478}479}480Q.resolve = Q;481482/**483* Performs a task in a future turn of the event loop.484* @param {Function} task485*/486Q.nextTick = nextTick;487488/**489* Controls whether or not long stack traces will be on490*/491Q.longStackSupport = false;492493/**494* Constructs a {promise, resolve, reject} object.495*496* `resolve` is a callback to invoke with a more resolved value for the497* promise. To fulfill the promise, invoke `resolve` with any value that is498* not a thenable. To reject the promise, invoke `resolve` with a rejected499* thenable, or invoke `reject` with the reason directly. To resolve the500* promise to another thenable, thus putting it in the same state, invoke501* `resolve` with that other thenable.502*/503Q.defer = defer;504function defer() {505// if "messages" is an "Array", that indicates that the promise has not yet506// been resolved. If it is "undefined", it has been resolved. Each507// element of the messages array is itself an array of complete arguments to508// forward to the resolved promise. We coerce the resolution value to a509// promise using the `resolve` function because it handles both fully510// non-thenable values and other thenables gracefully.511var messages = [], progressListeners = [], resolvedPromise;512513var deferred = object_create(defer.prototype);514var promise = object_create(Promise.prototype);515516promise.promiseDispatch = function (resolve, op, operands) {517var args = array_slice(arguments);518if (messages) {519messages.push(args);520if (op === "when" && operands[1]) { // progress operand521progressListeners.push(operands[1]);522}523} else {524nextTick(function () {525resolvedPromise.promiseDispatch.apply(resolvedPromise, args);526});527}528};529530// XXX deprecated531promise.valueOf = deprecate(function () {532if (messages) {533return promise;534}535var nearerValue = nearer(resolvedPromise);536if (isPromise(nearerValue)) {537resolvedPromise = nearerValue; // shorten chain538}539return nearerValue;540}, "valueOf", "inspect");541542promise.inspect = function () {543if (!resolvedPromise) {544return { state: "pending" };545}546return resolvedPromise.inspect();547};548549if (Q.longStackSupport && hasStacks) {550try {551throw new Error();552} catch (e) {553// NOTE: don't try to use `Error.captureStackTrace` or transfer the554// accessor around; that causes memory leaks as per GH-111. Just555// reify the stack trace as a string ASAP.556//557// At the same time, cut off the first line; it's always just558// "[object Promise]\n", as per the `toString`.559promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);560}561}562563// NOTE: we do the checks for `resolvedPromise` in each method, instead of564// consolidating them into `become`, since otherwise we'd create new565// promises with the lines `become(whatever(value))`. See e.g. GH-252.566567function become(newPromise) {568resolvedPromise = newPromise;569promise.source = newPromise;570571array_reduce(messages, function (undefined, message) {572nextTick(function () {573newPromise.promiseDispatch.apply(newPromise, message);574});575}, void 0);576577messages = void 0;578progressListeners = void 0;579}580581deferred.promise = promise;582deferred.resolve = function (value) {583if (resolvedPromise) {584return;585}586587become(Q(value));588};589590deferred.fulfill = function (value) {591if (resolvedPromise) {592return;593}594595become(fulfill(value));596};597deferred.reject = function (reason) {598if (resolvedPromise) {599return;600}601602become(reject(reason));603};604deferred.notify = function (progress) {605if (resolvedPromise) {606return;607}608609array_reduce(progressListeners, function (undefined, progressListener) {610nextTick(function () {611progressListener(progress);612});613}, void 0);614};615616return deferred;617}618619/**620* Creates a Node-style callback that will resolve or reject the deferred621* promise.622* @returns a nodeback623*/624defer.prototype.makeNodeResolver = function () {625var self = this;626return function (error, value) {627if (error) {628self.reject(error);629} else if (arguments.length > 2) {630self.resolve(array_slice(arguments, 1));631} else {632self.resolve(value);633}634};635};636637/**638* @param resolver {Function} a function that returns nothing and accepts639* the resolve, reject, and notify functions for a deferred.640* @returns a promise that may be resolved with the given resolve and reject641* functions, or rejected by a thrown exception in resolver642*/643Q.promise = promise;644function promise(resolver) {645if (typeof resolver !== "function") {646throw new TypeError("resolver must be a function.");647}648var deferred = defer();649try {650resolver(deferred.resolve, deferred.reject, deferred.notify);651} catch (reason) {652deferred.reject(reason);653}654return deferred.promise;655}656657// XXX experimental. This method is a way to denote that a local value is658// serializable and should be immediately dispatched to a remote upon request,659// instead of passing a reference.660Q.passByCopy = function (object) {661//freeze(object);662//passByCopies.set(object, true);663return object;664};665666Promise.prototype.passByCopy = function () {667//freeze(object);668//passByCopies.set(object, true);669return this;670};671672/**673* If two promises eventually fulfill to the same value, promises that value,674* but otherwise rejects.675* @param x {Any*}676* @param y {Any*}677* @returns {Any*} a promise for x and y if they are the same, but a rejection678* otherwise.679*680*/681Q.join = function (x, y) {682return Q(x).join(y);683};684685Promise.prototype.join = function (that) {686return Q([this, that]).spread(function (x, y) {687if (x === y) {688// TODO: "===" should be Object.is or equiv689return x;690} else {691throw new Error("Can't join: not the same: " + x + " " + y);692}693});694};695696/**697* Returns a promise for the first of an array of promises to become fulfilled.698* @param answers {Array[Any*]} promises to race699* @returns {Any*} the first promise to be fulfilled700*/701Q.race = race;702function race(answerPs) {703return promise(function(resolve, reject) {704// Switch to this once we can assume at least ES5705// answerPs.forEach(function(answerP) {706// Q(answerP).then(resolve, reject);707// });708// Use this in the meantime709for (var i = 0, len = answerPs.length; i < len; i++) {710Q(answerPs[i]).then(resolve, reject);711}712});713}714715Promise.prototype.race = function () {716return this.then(Q.race);717};718719/**720* Constructs a Promise with a promise descriptor object and optional fallback721* function. The descriptor contains methods like when(rejected), get(name),722* set(name, value), post(name, args), and delete(name), which all723* return either a value, a promise for a value, or a rejection. The fallback724* accepts the operation name, a resolver, and any further arguments that would725* have been forwarded to the appropriate method above had a method been726* provided with the proper name. The API makes no guarantees about the nature727* of the returned object, apart from that it is usable whereever promises are728* bought and sold.729*/730Q.makePromise = Promise;731function Promise(descriptor, fallback, inspect) {732if (fallback === void 0) {733fallback = function (op) {734return reject(new Error(735"Promise does not support operation: " + op736));737};738}739if (inspect === void 0) {740inspect = function () {741return {state: "unknown"};742};743}744745var promise = object_create(Promise.prototype);746747promise.promiseDispatch = function (resolve, op, args) {748var result;749try {750if (descriptor[op]) {751result = descriptor[op].apply(promise, args);752} else {753result = fallback.call(promise, op, args);754}755} catch (exception) {756result = reject(exception);757}758if (resolve) {759resolve(result);760}761};762763promise.inspect = inspect;764765// XXX deprecated `valueOf` and `exception` support766if (inspect) {767var inspected = inspect();768if (inspected.state === "rejected") {769promise.exception = inspected.reason;770}771772promise.valueOf = deprecate(function () {773var inspected = inspect();774if (inspected.state === "pending" ||775inspected.state === "rejected") {776return promise;777}778return inspected.value;779});780}781782return promise;783}784785Promise.prototype.toString = function () {786return "[object Promise]";787};788789Promise.prototype.then = function (fulfilled, rejected, progressed) {790var self = this;791var deferred = defer();792var done = false; // ensure the untrusted promise makes at most a793// single call to one of the callbacks794795function _fulfilled(value) {796try {797return typeof fulfilled === "function" ? fulfilled(value) : value;798} catch (exception) {799return reject(exception);800}801}802803function _rejected(exception) {804if (typeof rejected === "function") {805makeStackTraceLong(exception, self);806try {807return rejected(exception);808} catch (newException) {809return reject(newException);810}811}812return reject(exception);813}814815function _progressed(value) {816return typeof progressed === "function" ? progressed(value) : value;817}818819nextTick(function () {820self.promiseDispatch(function (value) {821if (done) {822return;823}824done = true;825826deferred.resolve(_fulfilled(value));827}, "when", [function (exception) {828if (done) {829return;830}831done = true;832833deferred.resolve(_rejected(exception));834}]);835});836837// Progress propagator need to be attached in the current tick.838self.promiseDispatch(void 0, "when", [void 0, function (value) {839var newValue;840var threw = false;841try {842newValue = _progressed(value);843} catch (e) {844threw = true;845if (Q.onerror) {846Q.onerror(e);847} else {848throw e;849}850}851852if (!threw) {853deferred.notify(newValue);854}855}]);856857return deferred.promise;858};859860/**861* Registers an observer on a promise.862*863* Guarantees:864*865* 1. that fulfilled and rejected will be called only once.866* 2. that either the fulfilled callback or the rejected callback will be867* called, but not both.868* 3. that fulfilled and rejected will not be called in this turn.869*870* @param value promise or immediate reference to observe871* @param fulfilled function to be called with the fulfilled value872* @param rejected function to be called with the rejection exception873* @param progressed function to be called on any progress notifications874* @return promise for the return value from the invoked callback875*/876Q.when = when;877function when(value, fulfilled, rejected, progressed) {878return Q(value).then(fulfilled, rejected, progressed);879}880881Promise.prototype.thenResolve = function (value) {882return this.then(function () { return value; });883};884885Q.thenResolve = function (promise, value) {886return Q(promise).thenResolve(value);887};888889Promise.prototype.thenReject = function (reason) {890return this.then(function () { throw reason; });891};892893Q.thenReject = function (promise, reason) {894return Q(promise).thenReject(reason);895};896897/**898* If an object is not a promise, it is as "near" as possible.899* If a promise is rejected, it is as "near" as possible too.900* If it’s a fulfilled promise, the fulfillment value is nearer.901* If it’s a deferred promise and the deferred has been resolved, the902* resolution is "nearer".903* @param object904* @returns most resolved (nearest) form of the object905*/906907// XXX should we re-do this?908Q.nearer = nearer;909function nearer(value) {910if (isPromise(value)) {911var inspected = value.inspect();912if (inspected.state === "fulfilled") {913return inspected.value;914}915}916return value;917}918919/**920* @returns whether the given object is a promise.921* Otherwise it is a fulfilled value.922*/923Q.isPromise = isPromise;924function isPromise(object) {925return isObject(object) &&926typeof object.promiseDispatch === "function" &&927typeof object.inspect === "function";928}929930Q.isPromiseAlike = isPromiseAlike;931function isPromiseAlike(object) {932return isObject(object) && typeof object.then === "function";933}934935/**936* @returns whether the given object is a pending promise, meaning not937* fulfilled or rejected.938*/939Q.isPending = isPending;940function isPending(object) {941return isPromise(object) && object.inspect().state === "pending";942}943944Promise.prototype.isPending = function () {945return this.inspect().state === "pending";946};947948/**949* @returns whether the given object is a value or fulfilled950* promise.951*/952Q.isFulfilled = isFulfilled;953function isFulfilled(object) {954return !isPromise(object) || object.inspect().state === "fulfilled";955}956957Promise.prototype.isFulfilled = function () {958return this.inspect().state === "fulfilled";959};960961/**962* @returns whether the given object is a rejected promise.963*/964Q.isRejected = isRejected;965function isRejected(object) {966return isPromise(object) && object.inspect().state === "rejected";967}968969Promise.prototype.isRejected = function () {970return this.inspect().state === "rejected";971};972973//// BEGIN UNHANDLED REJECTION TRACKING974975// This promise library consumes exceptions thrown in handlers so they can be976// handled by a subsequent promise. The exceptions get added to this array when977// they are created, and removed when they are handled. Note that in ES6 or978// shimmed environments, this would naturally be a `Set`.979var unhandledReasons = [];980var unhandledRejections = [];981var unhandledReasonsDisplayed = false;982var trackUnhandledRejections = true;983function displayUnhandledReasons() {984if (985!unhandledReasonsDisplayed &&986typeof window !== "undefined" &&987!window.Touch &&988window.console989) {990console.warn("[Q] Unhandled rejection reasons (should be empty):",991unhandledReasons);992}993994unhandledReasonsDisplayed = true;995}996997function logUnhandledReasons() {998for (var i = 0; i < unhandledReasons.length; i++) {999var reason = unhandledReasons[i];1000console.warn("Unhandled rejection reason:", reason);1001}1002}10031004function resetUnhandledRejections() {1005unhandledReasons.length = 0;1006unhandledRejections.length = 0;1007unhandledReasonsDisplayed = false;10081009if (!trackUnhandledRejections) {1010trackUnhandledRejections = true;10111012// Show unhandled rejection reasons if Node exits without handling an1013// outstanding rejection. (Note that Browserify presently produces a1014// `process` global without the `EventEmitter` `on` method.)1015if (typeof process !== "undefined" && process.on) {1016process.on("exit", logUnhandledReasons);1017}1018}1019}10201021function trackRejection(promise, reason) {1022if (!trackUnhandledRejections) {1023return;1024}10251026unhandledRejections.push(promise);1027if (reason && typeof reason.stack !== "undefined") {1028unhandledReasons.push(reason.stack);1029} else {1030unhandledReasons.push("(no stack) " + reason);1031}1032displayUnhandledReasons();1033}10341035function untrackRejection(promise) {1036if (!trackUnhandledRejections) {1037return;1038}10391040var at = array_indexOf(unhandledRejections, promise);1041if (at !== -1) {1042unhandledRejections.splice(at, 1);1043unhandledReasons.splice(at, 1);1044}1045}10461047Q.resetUnhandledRejections = resetUnhandledRejections;10481049Q.getUnhandledReasons = function () {1050// Make a copy so that consumers can't interfere with our internal state.1051return unhandledReasons.slice();1052};10531054Q.stopUnhandledRejectionTracking = function () {1055resetUnhandledRejections();1056if (typeof process !== "undefined" && process.on) {1057process.removeListener("exit", logUnhandledReasons);1058}1059trackUnhandledRejections = false;1060};10611062resetUnhandledRejections();10631064//// END UNHANDLED REJECTION TRACKING10651066/**1067* Constructs a rejected promise.1068* @param reason value describing the failure1069*/1070Q.reject = reject;1071function reject(reason) {1072var rejection = Promise({1073"when": function (rejected) {1074// note that the error has been handled1075if (rejected) {1076untrackRejection(this);1077}1078return rejected ? rejected(reason) : this;1079}1080}, function fallback() {1081return this;1082}, function inspect() {1083return { state: "rejected", reason: reason };1084});10851086// Note that the reason has not been handled.1087trackRejection(rejection, reason);10881089return rejection;1090}10911092/**1093* Constructs a fulfilled promise for an immediate reference.1094* @param value immediate reference1095*/1096Q.fulfill = fulfill;1097function fulfill(value) {1098return Promise({1099"when": function () {1100return value;1101},1102"get": function (name) {1103return value[name];1104},1105"set": function (name, rhs) {1106value[name] = rhs;1107},1108"delete": function (name) {1109delete value[name];1110},1111"post": function (name, args) {1112// Mark Miller proposes that post with no name should apply a1113// promised function.1114if (name === null || name === void 0) {1115return value.apply(void 0, args);1116} else {1117return value[name].apply(value, args);1118}1119},1120"apply": function (thisp, args) {1121return value.apply(thisp, args);1122},1123"keys": function () {1124return object_keys(value);1125}1126}, void 0, function inspect() {1127return { state: "fulfilled", value: value };1128});1129}11301131/**1132* Converts thenables to Q promises.1133* @param promise thenable promise1134* @returns a Q promise1135*/1136function coerce(promise) {1137var deferred = defer();1138nextTick(function () {1139try {1140promise.then(deferred.resolve, deferred.reject, deferred.notify);1141} catch (exception) {1142deferred.reject(exception);1143}1144});1145return deferred.promise;1146}11471148/**1149* Annotates an object such that it will never be1150* transferred away from this process over any promise1151* communication channel.1152* @param object1153* @returns promise a wrapping of that object that1154* additionally responds to the "isDef" message1155* without a rejection.1156*/1157Q.master = master;1158function master(object) {1159return Promise({1160"isDef": function () {}1161}, function fallback(op, args) {1162return dispatch(object, op, args);1163}, function () {1164return Q(object).inspect();1165});1166}11671168/**1169* Spreads the values of a promised array of arguments into the1170* fulfillment callback.1171* @param fulfilled callback that receives variadic arguments from the1172* promised array1173* @param rejected callback that receives the exception if the promise1174* is rejected.1175* @returns a promise for the return value or thrown exception of1176* either callback.1177*/1178Q.spread = spread;1179function spread(value, fulfilled, rejected) {1180return Q(value).spread(fulfilled, rejected);1181}11821183Promise.prototype.spread = function (fulfilled, rejected) {1184return this.all().then(function (array) {1185return fulfilled.apply(void 0, array);1186}, rejected);1187};11881189/**1190* The async function is a decorator for generator functions, turning1191* them into asynchronous generators. Although generators are only part1192* of the newest ECMAScript 6 drafts, this code does not cause syntax1193* errors in older engines. This code should continue to work and will1194* in fact improve over time as the language improves.1195*1196* ES6 generators are currently part of V8 version 3.19 with the1197* --harmony-generators runtime flag enabled. SpiderMonkey has had them1198* for longer, but under an older Python-inspired form. This function1199* works on both kinds of generators.1200*1201* Decorates a generator function such that:1202* - it may yield promises1203* - execution will continue when that promise is fulfilled1204* - the value of the yield expression will be the fulfilled value1205* - it returns a promise for the return value (when the generator1206* stops iterating)1207* - the decorated function returns a promise for the return value1208* of the generator or the first rejected promise among those1209* yielded.1210* - if an error is thrown in the generator, it propagates through1211* every following yield until it is caught, or until it escapes1212* the generator function altogether, and is translated into a1213* rejection for the promise returned by the decorated generator.1214*/1215Q.async = async;1216function async(makeGenerator) {1217return function () {1218// when verb is "send", arg is a value1219// when verb is "throw", arg is an exception1220function continuer(verb, arg) {1221var result;1222if (hasES6Generators) {1223try {1224result = generator[verb](arg);1225} catch (exception) {1226return reject(exception);1227}1228if (result.done) {1229return result.value;1230} else {1231return when(result.value, callback, errback);1232}1233} else {1234// FIXME: Remove this case when SM does ES6 generators.1235try {1236result = generator[verb](arg);1237} catch (exception) {1238if (isStopIteration(exception)) {1239return exception.value;1240} else {1241return reject(exception);1242}1243}1244return when(result, callback, errback);1245}1246}1247var generator = makeGenerator.apply(this, arguments);1248var callback = continuer.bind(continuer, "next");1249var errback = continuer.bind(continuer, "throw");1250return callback();1251};1252}12531254/**1255* The spawn function is a small wrapper around async that immediately1256* calls the generator and also ends the promise chain, so that any1257* unhandled errors are thrown instead of forwarded to the error1258* handler. This is useful because it's extremely common to run1259* generators at the top-level to work with libraries.1260*/1261Q.spawn = spawn;1262function spawn(makeGenerator) {1263Q.done(Q.async(makeGenerator)());1264}12651266// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.1267/**1268* Throws a ReturnValue exception to stop an asynchronous generator.1269*1270* This interface is a stop-gap measure to support generator return1271* values in older Firefox/SpiderMonkey. In browsers that support ES61272* generators like Chromium 29, just use "return" in your generator1273* functions.1274*1275* @param value the return value for the surrounding generator1276* @throws ReturnValue exception with the value.1277* @example1278* // ES6 style1279* Q.async(function* () {1280* var foo = yield getFooPromise();1281* var bar = yield getBarPromise();1282* return foo + bar;1283* })1284* // Older SpiderMonkey style1285* Q.async(function () {1286* var foo = yield getFooPromise();1287* var bar = yield getBarPromise();1288* Q.return(foo + bar);1289* })1290*/1291Q["return"] = _return;1292function _return(value) {1293throw new QReturnValue(value);1294}12951296/**1297* The promised function decorator ensures that any promise arguments1298* are settled and passed as values (`this` is also settled and passed1299* as a value). It will also ensure that the result of a function is1300* always a promise.1301*1302* @example1303* var add = Q.promised(function (a, b) {1304* return a + b;1305* });1306* add(Q(a), Q(B));1307*1308* @param {function} callback The function to decorate1309* @returns {function} a function that has been decorated.1310*/1311Q.promised = promised;1312function promised(callback) {1313return function () {1314return spread([this, all(arguments)], function (self, args) {1315return callback.apply(self, args);1316});1317};1318}13191320/**1321* sends a message to a value in a future turn1322* @param object* the recipient1323* @param op the name of the message operation, e.g., "when",1324* @param args further arguments to be forwarded to the operation1325* @returns result {Promise} a promise for the result of the operation1326*/1327Q.dispatch = dispatch;1328function dispatch(object, op, args) {1329return Q(object).dispatch(op, args);1330}13311332Promise.prototype.dispatch = function (op, args) {1333var self = this;1334var deferred = defer();1335nextTick(function () {1336self.promiseDispatch(deferred.resolve, op, args);1337});1338return deferred.promise;1339};13401341/**1342* Gets the value of a property in a future turn.1343* @param object promise or immediate reference for target object1344* @param name name of property to get1345* @return promise for the property value1346*/1347Q.get = function (object, key) {1348return Q(object).dispatch("get", [key]);1349};13501351Promise.prototype.get = function (key) {1352return this.dispatch("get", [key]);1353};13541355/**1356* Sets the value of a property in a future turn.1357* @param object promise or immediate reference for object object1358* @param name name of property to set1359* @param value new value of property1360* @return promise for the return value1361*/1362Q.set = function (object, key, value) {1363return Q(object).dispatch("set", [key, value]);1364};13651366Promise.prototype.set = function (key, value) {1367return this.dispatch("set", [key, value]);1368};13691370/**1371* Deletes a property in a future turn.1372* @param object promise or immediate reference for target object1373* @param name name of property to delete1374* @return promise for the return value1375*/1376Q.del = // XXX legacy1377Q["delete"] = function (object, key) {1378return Q(object).dispatch("delete", [key]);1379};13801381Promise.prototype.del = // XXX legacy1382Promise.prototype["delete"] = function (key) {1383return this.dispatch("delete", [key]);1384};13851386/**1387* Invokes a method in a future turn.1388* @param object promise or immediate reference for target object1389* @param name name of method to invoke1390* @param value a value to post, typically an array of1391* invocation arguments for promises that1392* are ultimately backed with `resolve` values,1393* as opposed to those backed with URLs1394* wherein the posted value can be any1395* JSON serializable object.1396* @return promise for the return value1397*/1398// bound locally because it is used by other methods1399Q.mapply = // XXX As proposed by "Redsandro"1400Q.post = function (object, name, args) {1401return Q(object).dispatch("post", [name, args]);1402};14031404Promise.prototype.mapply = // XXX As proposed by "Redsandro"1405Promise.prototype.post = function (name, args) {1406return this.dispatch("post", [name, args]);1407};14081409/**1410* Invokes a method in a future turn.1411* @param object promise or immediate reference for target object1412* @param name name of method to invoke1413* @param ...args array of invocation arguments1414* @return promise for the return value1415*/1416Q.send = // XXX Mark Miller's proposed parlance1417Q.mcall = // XXX As proposed by "Redsandro"1418Q.invoke = function (object, name /*...args*/) {1419return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);1420};14211422Promise.prototype.send = // XXX Mark Miller's proposed parlance1423Promise.prototype.mcall = // XXX As proposed by "Redsandro"1424Promise.prototype.invoke = function (name /*...args*/) {1425return this.dispatch("post", [name, array_slice(arguments, 1)]);1426};14271428/**1429* Applies the promised function in a future turn.1430* @param object promise or immediate reference for target function1431* @param args array of application arguments1432*/1433Q.fapply = function (object, args) {1434return Q(object).dispatch("apply", [void 0, args]);1435};14361437Promise.prototype.fapply = function (args) {1438return this.dispatch("apply", [void 0, args]);1439};14401441/**1442* Calls the promised function in a future turn.1443* @param object promise or immediate reference for target function1444* @param ...args array of application arguments1445*/1446Q["try"] =1447Q.fcall = function (object /* ...args*/) {1448return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);1449};14501451Promise.prototype.fcall = function (/*...args*/) {1452return this.dispatch("apply", [void 0, array_slice(arguments)]);1453};14541455/**1456* Binds the promised function, transforming return values into a fulfilled1457* promise and thrown errors into a rejected one.1458* @param object promise or immediate reference for target function1459* @param ...args array of application arguments1460*/1461Q.fbind = function (object /*...args*/) {1462var promise = Q(object);1463var args = array_slice(arguments, 1);1464return function fbound() {1465return promise.dispatch("apply", [1466this,1467args.concat(array_slice(arguments))1468]);1469};1470};1471Promise.prototype.fbind = function (/*...args*/) {1472var promise = this;1473var args = array_slice(arguments);1474return function fbound() {1475return promise.dispatch("apply", [1476this,1477args.concat(array_slice(arguments))1478]);1479};1480};14811482/**1483* Requests the names of the owned properties of a promised1484* object in a future turn.1485* @param object promise or immediate reference for target object1486* @return promise for the keys of the eventually settled object1487*/1488Q.keys = function (object) {1489return Q(object).dispatch("keys", []);1490};14911492Promise.prototype.keys = function () {1493return this.dispatch("keys", []);1494};14951496/**1497* Turns an array of promises into a promise for an array. If any of1498* the promises gets rejected, the whole array is rejected immediately.1499* @param {Array*} an array (or promise for an array) of values (or1500* promises for values)1501* @returns a promise for an array of the corresponding values1502*/1503// By Mark Miller1504// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled1505Q.all = all;1506function all(promises) {1507return when(promises, function (promises) {1508var countDown = 0;1509var deferred = defer();1510array_reduce(promises, function (undefined, promise, index) {1511var snapshot;1512if (1513isPromise(promise) &&1514(snapshot = promise.inspect()).state === "fulfilled"1515) {1516promises[index] = snapshot.value;1517} else {1518++countDown;1519when(1520promise,1521function (value) {1522promises[index] = value;1523if (--countDown === 0) {1524deferred.resolve(promises);1525}1526},1527deferred.reject,1528function (progress) {1529deferred.notify({ index: index, value: progress });1530}1531);1532}1533}, void 0);1534if (countDown === 0) {1535deferred.resolve(promises);1536}1537return deferred.promise;1538});1539}15401541Promise.prototype.all = function () {1542return all(this);1543};15441545/**1546* Waits for all promises to be settled, either fulfilled or1547* rejected. This is distinct from `all` since that would stop1548* waiting at the first rejection. The promise returned by1549* `allResolved` will never be rejected.1550* @param promises a promise for an array (or an array) of promises1551* (or values)1552* @return a promise for an array of promises1553*/1554Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");1555function allResolved(promises) {1556return when(promises, function (promises) {1557promises = array_map(promises, Q);1558return when(all(array_map(promises, function (promise) {1559return when(promise, noop, noop);1560})), function () {1561return promises;1562});1563});1564}15651566Promise.prototype.allResolved = function () {1567return allResolved(this);1568};15691570/**1571* @see Promise#allSettled1572*/1573Q.allSettled = allSettled;1574function allSettled(promises) {1575return Q(promises).allSettled();1576}15771578/**1579* Turns an array of promises into a promise for an array of their states (as1580* returned by `inspect`) when they have all settled.1581* @param {Array[Any*]} values an array (or promise for an array) of values (or1582* promises for values)1583* @returns {Array[State]} an array of states for the respective values.1584*/1585Promise.prototype.allSettled = function () {1586return this.then(function (promises) {1587return all(array_map(promises, function (promise) {1588promise = Q(promise);1589function regardless() {1590return promise.inspect();1591}1592return promise.then(regardless, regardless);1593}));1594});1595};15961597/**1598* Captures the failure of a promise, giving an oportunity to recover1599* with a callback. If the given promise is fulfilled, the returned1600* promise is fulfilled.1601* @param {Any*} promise for something1602* @param {Function} callback to fulfill the returned promise if the1603* given promise is rejected1604* @returns a promise for the return value of the callback1605*/1606Q.fail = // XXX legacy1607Q["catch"] = function (object, rejected) {1608return Q(object).then(void 0, rejected);1609};16101611Promise.prototype.fail = // XXX legacy1612Promise.prototype["catch"] = function (rejected) {1613return this.then(void 0, rejected);1614};16151616/**1617* Attaches a listener that can respond to progress notifications from a1618* promise's originating deferred. This listener receives the exact arguments1619* passed to ``deferred.notify``.1620* @param {Any*} promise for something1621* @param {Function} callback to receive any progress notifications1622* @returns the given promise, unchanged1623*/1624Q.progress = progress;1625function progress(object, progressed) {1626return Q(object).then(void 0, void 0, progressed);1627}16281629Promise.prototype.progress = function (progressed) {1630return this.then(void 0, void 0, progressed);1631};16321633/**1634* Provides an opportunity to observe the settling of a promise,1635* regardless of whether the promise is fulfilled or rejected. Forwards1636* the resolution to the returned promise when the callback is done.1637* The callback can return a promise to defer completion.1638* @param {Any*} promise1639* @param {Function} callback to observe the resolution of the given1640* promise, takes no arguments.1641* @returns a promise for the resolution of the given promise when1642* ``fin`` is done.1643*/1644Q.fin = // XXX legacy1645Q["finally"] = function (object, callback) {1646return Q(object)["finally"](callback);1647};16481649Promise.prototype.fin = // XXX legacy1650Promise.prototype["finally"] = function (callback) {1651callback = Q(callback);1652return this.then(function (value) {1653return callback.fcall().then(function () {1654return value;1655});1656}, function (reason) {1657// TODO attempt to recycle the rejection with "this".1658return callback.fcall().then(function () {1659throw reason;1660});1661});1662};16631664/**1665* Terminates a chain of promises, forcing rejections to be1666* thrown as exceptions.1667* @param {Any*} promise at the end of a chain of promises1668* @returns nothing1669*/1670Q.done = function (object, fulfilled, rejected, progress) {1671return Q(object).done(fulfilled, rejected, progress);1672};16731674Promise.prototype.done = function (fulfilled, rejected, progress) {1675var onUnhandledError = function (error) {1676// forward to a future turn so that ``when``1677// does not catch it and turn it into a rejection.1678nextTick(function () {1679makeStackTraceLong(error, promise);1680if (Q.onerror) {1681Q.onerror(error);1682} else {1683throw error;1684}1685});1686};16871688// Avoid unnecessary `nextTick`ing via an unnecessary `when`.1689var promise = fulfilled || rejected || progress ?1690this.then(fulfilled, rejected, progress) :1691this;16921693if (typeof process === "object" && process && process.domain) {1694onUnhandledError = process.domain.bind(onUnhandledError);1695}16961697promise.then(void 0, onUnhandledError);1698};16991700/**1701* Causes a promise to be rejected if it does not get fulfilled before1702* some milliseconds time out.1703* @param {Any*} promise1704* @param {Number} milliseconds timeout1705* @param {String} custom error message (optional)1706* @returns a promise for the resolution of the given promise if it is1707* fulfilled before the timeout, otherwise rejected.1708*/1709Q.timeout = function (object, ms, message) {1710return Q(object).timeout(ms, message);1711};17121713Promise.prototype.timeout = function (ms, message) {1714var deferred = defer();1715var timeoutId = setTimeout(function () {1716deferred.reject(new Error(message || "Timed out after " + ms + " ms"));1717}, ms);17181719this.then(function (value) {1720clearTimeout(timeoutId);1721deferred.resolve(value);1722}, function (exception) {1723clearTimeout(timeoutId);1724deferred.reject(exception);1725}, deferred.notify);17261727return deferred.promise;1728};17291730/**1731* Returns a promise for the given value (or promised value), some1732* milliseconds after it resolved. Passes rejections immediately.1733* @param {Any*} promise1734* @param {Number} milliseconds1735* @returns a promise for the resolution of the given promise after milliseconds1736* time has elapsed since the resolution of the given promise.1737* If the given promise rejects, that is passed immediately.1738*/1739Q.delay = function (object, timeout) {1740if (timeout === void 0) {1741timeout = object;1742object = void 0;1743}1744return Q(object).delay(timeout);1745};17461747Promise.prototype.delay = function (timeout) {1748return this.then(function (value) {1749var deferred = defer();1750setTimeout(function () {1751deferred.resolve(value);1752}, timeout);1753return deferred.promise;1754});1755};17561757/**1758* Passes a continuation to a Node function, which is called with the given1759* arguments provided as an array, and returns a promise.1760*1761* Q.nfapply(FS.readFile, [__filename])1762* .then(function (content) {1763* })1764*1765*/1766Q.nfapply = function (callback, args) {1767return Q(callback).nfapply(args);1768};17691770Promise.prototype.nfapply = function (args) {1771var deferred = defer();1772var nodeArgs = array_slice(args);1773nodeArgs.push(deferred.makeNodeResolver());1774this.fapply(nodeArgs).fail(deferred.reject);1775return deferred.promise;1776};17771778/**1779* Passes a continuation to a Node function, which is called with the given1780* arguments provided individually, and returns a promise.1781* @example1782* Q.nfcall(FS.readFile, __filename)1783* .then(function (content) {1784* })1785*1786*/1787Q.nfcall = function (callback /*...args*/) {1788var args = array_slice(arguments, 1);1789return Q(callback).nfapply(args);1790};17911792Promise.prototype.nfcall = function (/*...args*/) {1793var nodeArgs = array_slice(arguments);1794var deferred = defer();1795nodeArgs.push(deferred.makeNodeResolver());1796this.fapply(nodeArgs).fail(deferred.reject);1797return deferred.promise;1798};17991800/**1801* Wraps a NodeJS continuation passing function and returns an equivalent1802* version that returns a promise.1803* @example1804* Q.nfbind(FS.readFile, __filename)("utf-8")1805* .then(console.log)1806* .done()1807*/1808Q.nfbind =1809Q.denodeify = function (callback /*...args*/) {1810var baseArgs = array_slice(arguments, 1);1811return function () {1812var nodeArgs = baseArgs.concat(array_slice(arguments));1813var deferred = defer();1814nodeArgs.push(deferred.makeNodeResolver());1815Q(callback).fapply(nodeArgs).fail(deferred.reject);1816return deferred.promise;1817};1818};18191820Promise.prototype.nfbind =1821Promise.prototype.denodeify = function (/*...args*/) {1822var args = array_slice(arguments);1823args.unshift(this);1824return Q.denodeify.apply(void 0, args);1825};18261827Q.nbind = function (callback, thisp /*...args*/) {1828var baseArgs = array_slice(arguments, 2);1829return function () {1830var nodeArgs = baseArgs.concat(array_slice(arguments));1831var deferred = defer();1832nodeArgs.push(deferred.makeNodeResolver());1833function bound() {1834return callback.apply(thisp, arguments);1835}1836Q(bound).fapply(nodeArgs).fail(deferred.reject);1837return deferred.promise;1838};1839};18401841Promise.prototype.nbind = function (/*thisp, ...args*/) {1842var args = array_slice(arguments, 0);1843args.unshift(this);1844return Q.nbind.apply(void 0, args);1845};18461847/**1848* Calls a method of a Node-style object that accepts a Node-style1849* callback with a given array of arguments, plus a provided callback.1850* @param object an object that has the named method1851* @param {String} name name of the method of object1852* @param {Array} args arguments to pass to the method; the callback1853* will be provided by Q and appended to these arguments.1854* @returns a promise for the value or error1855*/1856Q.nmapply = // XXX As proposed by "Redsandro"1857Q.npost = function (object, name, args) {1858return Q(object).npost(name, args);1859};18601861Promise.prototype.nmapply = // XXX As proposed by "Redsandro"1862Promise.prototype.npost = function (name, args) {1863var nodeArgs = array_slice(args || []);1864var deferred = defer();1865nodeArgs.push(deferred.makeNodeResolver());1866this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);1867return deferred.promise;1868};18691870/**1871* Calls a method of a Node-style object that accepts a Node-style1872* callback, forwarding the given variadic arguments, plus a provided1873* callback argument.1874* @param object an object that has the named method1875* @param {String} name name of the method of object1876* @param ...args arguments to pass to the method; the callback will1877* be provided by Q and appended to these arguments.1878* @returns a promise for the value or error1879*/1880Q.nsend = // XXX Based on Mark Miller's proposed "send"1881Q.nmcall = // XXX Based on "Redsandro's" proposal1882Q.ninvoke = function (object, name /*...args*/) {1883var nodeArgs = array_slice(arguments, 2);1884var deferred = defer();1885nodeArgs.push(deferred.makeNodeResolver());1886Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);1887return deferred.promise;1888};18891890Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"1891Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal1892Promise.prototype.ninvoke = function (name /*...args*/) {1893var nodeArgs = array_slice(arguments, 1);1894var deferred = defer();1895nodeArgs.push(deferred.makeNodeResolver());1896this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);1897return deferred.promise;1898};18991900/**1901* If a function would like to support both Node continuation-passing-style and1902* promise-returning-style, it can end its internal promise chain with1903* `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user1904* elects to use a nodeback, the result will be sent there. If they do not1905* pass a nodeback, they will receive the result promise.1906* @param object a result (or a promise for a result)1907* @param {Function} nodeback a Node.js-style callback1908* @returns either the promise or nothing1909*/1910Q.nodeify = nodeify;1911function nodeify(object, nodeback) {1912return Q(object).nodeify(nodeback);1913}19141915Promise.prototype.nodeify = function (nodeback) {1916if (nodeback) {1917this.then(function (value) {1918nextTick(function () {1919nodeback(null, value);1920});1921}, function (error) {1922nextTick(function () {1923nodeback(error);1924});1925});1926} else {1927return this;1928}1929};19301931// All code before this point will be filtered from stack traces.1932var qEndingLine = captureLine();19331934return Q;19351936});193719381939