q.js 61KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049
  1. // vim:ts=4:sts=4:sw=4:
  2. /*!
  3. *
  4. * Copyright 2009-2012 Kris Kowal under the terms of the MIT
  5. * license found at http://github.com/kriskowal/q/raw/master/LICENSE
  6. *
  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
  11. *
  12. * With parts by Mark Miller
  13. * Copyright (C) 2011 Google Inc.
  14. *
  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
  18. *
  19. * http://www.apache.org/licenses/LICENSE-2.0
  20. *
  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.
  26. *
  27. */
  28. (function (definition) {
  29. "use strict";
  30. // This file will function properly as a <script> tag, or a module
  31. // using CommonJS and NodeJS or RequireJS module formats. In
  32. // Common/Node/RequireJS, the module exports the Q API and when
  33. // executed as a simple <script>, it creates a Q global instead.
  34. // Montage Require
  35. if (typeof bootstrap === "function") {
  36. bootstrap("promise", definition);
  37. // CommonJS
  38. } else if (typeof exports === "object" && typeof module === "object") {
  39. module.exports = definition();
  40. // RequireJS
  41. } else if (typeof define === "function" && define.amd) {
  42. define(definition);
  43. // SES (Secure EcmaScript)
  44. } else if (typeof ses !== "undefined") {
  45. if (!ses.ok()) {
  46. return;
  47. } else {
  48. ses.makeQ = definition;
  49. }
  50. // <script>
  51. } else if (typeof window !== "undefined" || typeof self !== "undefined") {
  52. // Prefer window over self for add-on scripts. Use self for
  53. // non-windowed contexts.
  54. var global = typeof window !== "undefined" ? window : self;
  55. // Get the `window` object, save the previous Q global
  56. // and initialize Q as a global.
  57. var previousQ = global.Q;
  58. global.Q = definition();
  59. // Add a noConflict function so Q can be removed from the
  60. // global namespace.
  61. global.Q.noConflict = function () {
  62. global.Q = previousQ;
  63. return this;
  64. };
  65. } else {
  66. throw new Error("This environment was not anticipated by Q. Please file a bug.");
  67. }
  68. })(function () {
  69. "use strict";
  70. var hasStacks = false;
  71. try {
  72. throw new Error();
  73. } catch (e) {
  74. hasStacks = !!e.stack;
  75. }
  76. // All code after this point will be filtered from stack traces reported
  77. // by Q.
  78. var qStartingLine = captureLine();
  79. var qFileName;
  80. // shims
  81. // used for fallback in "allResolved"
  82. var noop = function () {};
  83. // Use the fastest possible means to execute a task in a future turn
  84. // of the event loop.
  85. var nextTick =(function () {
  86. // linked list of tasks (single, with head node)
  87. var head = {task: void 0, next: null};
  88. var tail = head;
  89. var flushing = false;
  90. var requestTick = void 0;
  91. var isNodeJS = false;
  92. // queue for late tasks, used by unhandled rejection tracking
  93. var laterQueue = [];
  94. function flush() {
  95. /* jshint loopfunc: true */
  96. var task, domain;
  97. while (head.next) {
  98. head = head.next;
  99. task = head.task;
  100. head.task = void 0;
  101. domain = head.domain;
  102. if (domain) {
  103. head.domain = void 0;
  104. domain.enter();
  105. }
  106. runSingle(task, domain);
  107. }
  108. while (laterQueue.length) {
  109. task = laterQueue.pop();
  110. runSingle(task);
  111. }
  112. flushing = false;
  113. }
  114. // runs a single function in the async queue
  115. function runSingle(task, domain) {
  116. try {
  117. task();
  118. } catch (e) {
  119. if (isNodeJS) {
  120. // In node, uncaught exceptions are considered fatal errors.
  121. // Re-throw them synchronously to interrupt flushing!
  122. // Ensure continuation if the uncaught exception is suppressed
  123. // listening "uncaughtException" events (as domains does).
  124. // Continue in next event to avoid tick recursion.
  125. if (domain) {
  126. domain.exit();
  127. }
  128. setTimeout(flush, 0);
  129. if (domain) {
  130. domain.enter();
  131. }
  132. throw e;
  133. } else {
  134. // In browsers, uncaught exceptions are not fatal.
  135. // Re-throw them asynchronously to avoid slow-downs.
  136. setTimeout(function () {
  137. throw e;
  138. }, 0);
  139. }
  140. }
  141. if (domain) {
  142. domain.exit();
  143. }
  144. }
  145. nextTick = function (task) {
  146. tail = tail.next = {
  147. task: task,
  148. domain: isNodeJS && process.domain,
  149. next: null
  150. };
  151. if (!flushing) {
  152. flushing = true;
  153. requestTick();
  154. }
  155. };
  156. if (typeof process === "object" &&
  157. process.toString() === "[object process]" && process.nextTick) {
  158. // Ensure Q is in a real Node environment, with a `process.nextTick`.
  159. // To see through fake Node environments:
  160. // * Mocha test runner - exposes a `process` global without a `nextTick`
  161. // * Browserify - exposes a `process.nexTick` function that uses
  162. // `setTimeout`. In this case `setImmediate` is preferred because
  163. // it is faster. Browserify's `process.toString()` yields
  164. // "[object Object]", while in a real Node environment
  165. // `process.nextTick()` yields "[object process]".
  166. isNodeJS = true;
  167. requestTick = function () {
  168. process.nextTick(flush);
  169. };
  170. } else if (typeof setImmediate === "function") {
  171. // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
  172. if (typeof window !== "undefined") {
  173. requestTick = setImmediate.bind(window, flush);
  174. } else {
  175. requestTick = function () {
  176. setImmediate(flush);
  177. };
  178. }
  179. } else if (typeof MessageChannel !== "undefined") {
  180. // modern browsers
  181. // http://www.nonblocking.io/2011/06/windownexttick.html
  182. var channel = new MessageChannel();
  183. // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
  184. // working message ports the first time a page loads.
  185. channel.port1.onmessage = function () {
  186. requestTick = requestPortTick;
  187. channel.port1.onmessage = flush;
  188. flush();
  189. };
  190. var requestPortTick = function () {
  191. // Opera requires us to provide a message payload, regardless of
  192. // whether we use it.
  193. channel.port2.postMessage(0);
  194. };
  195. requestTick = function () {
  196. setTimeout(flush, 0);
  197. requestPortTick();
  198. };
  199. } else {
  200. // old browsers
  201. requestTick = function () {
  202. setTimeout(flush, 0);
  203. };
  204. }
  205. // runs a task after all other tasks have been run
  206. // this is useful for unhandled rejection tracking that needs to happen
  207. // after all `then`d tasks have been run.
  208. nextTick.runAfter = function (task) {
  209. laterQueue.push(task);
  210. if (!flushing) {
  211. flushing = true;
  212. requestTick();
  213. }
  214. };
  215. return nextTick;
  216. })();
  217. // Attempt to make generics safe in the face of downstream
  218. // modifications.
  219. // There is no situation where this is necessary.
  220. // If you need a security guarantee, these primordials need to be
  221. // deeply frozen anyway, and if you don’t need a security guarantee,
  222. // this is just plain paranoid.
  223. // However, this **might** have the nice side-effect of reducing the size of
  224. // the minified code by reducing x.call() to merely x()
  225. // See Mark Miller’s explanation of what this does.
  226. // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
  227. var call = Function.call;
  228. function uncurryThis(f) {
  229. return function () {
  230. return call.apply(f, arguments);
  231. };
  232. }
  233. // This is equivalent, but slower:
  234. // uncurryThis = Function_bind.bind(Function_bind.call);
  235. // http://jsperf.com/uncurrythis
  236. var array_slice = uncurryThis(Array.prototype.slice);
  237. var array_reduce = uncurryThis(
  238. Array.prototype.reduce || function (callback, basis) {
  239. var index = 0,
  240. length = this.length;
  241. // concerning the initial value, if one is not provided
  242. if (arguments.length === 1) {
  243. // seek to the first value in the array, accounting
  244. // for the possibility that is is a sparse array
  245. do {
  246. if (index in this) {
  247. basis = this[index++];
  248. break;
  249. }
  250. if (++index >= length) {
  251. throw new TypeError();
  252. }
  253. } while (1);
  254. }
  255. // reduce
  256. for (; index < length; index++) {
  257. // account for the possibility that the array is sparse
  258. if (index in this) {
  259. basis = callback(basis, this[index], index);
  260. }
  261. }
  262. return basis;
  263. }
  264. );
  265. var array_indexOf = uncurryThis(
  266. Array.prototype.indexOf || function (value) {
  267. // not a very good shim, but good enough for our one use of it
  268. for (var i = 0; i < this.length; i++) {
  269. if (this[i] === value) {
  270. return i;
  271. }
  272. }
  273. return -1;
  274. }
  275. );
  276. var array_map = uncurryThis(
  277. Array.prototype.map || function (callback, thisp) {
  278. var self = this;
  279. var collect = [];
  280. array_reduce(self, function (undefined, value, index) {
  281. collect.push(callback.call(thisp, value, index, self));
  282. }, void 0);
  283. return collect;
  284. }
  285. );
  286. var object_create = Object.create || function (prototype) {
  287. function Type() { }
  288. Type.prototype = prototype;
  289. return new Type();
  290. };
  291. var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
  292. var object_keys = Object.keys || function (object) {
  293. var keys = [];
  294. for (var key in object) {
  295. if (object_hasOwnProperty(object, key)) {
  296. keys.push(key);
  297. }
  298. }
  299. return keys;
  300. };
  301. var object_toString = uncurryThis(Object.prototype.toString);
  302. function isObject(value) {
  303. return value === Object(value);
  304. }
  305. // generator related shims
  306. // FIXME: Remove this function once ES6 generators are in SpiderMonkey.
  307. function isStopIteration(exception) {
  308. return (
  309. object_toString(exception) === "[object StopIteration]" ||
  310. exception instanceof QReturnValue
  311. );
  312. }
  313. // FIXME: Remove this helper and Q.return once ES6 generators are in
  314. // SpiderMonkey.
  315. var QReturnValue;
  316. if (typeof ReturnValue !== "undefined") {
  317. QReturnValue = ReturnValue;
  318. } else {
  319. QReturnValue = function (value) {
  320. this.value = value;
  321. };
  322. }
  323. // long stack traces
  324. var STACK_JUMP_SEPARATOR = "From previous event:";
  325. function makeStackTraceLong(error, promise) {
  326. // If possible, transform the error stack trace by removing Node and Q
  327. // cruft, then concatenating with the stack trace of `promise`. See #57.
  328. if (hasStacks &&
  329. promise.stack &&
  330. typeof error === "object" &&
  331. error !== null &&
  332. error.stack &&
  333. error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
  334. ) {
  335. var stacks = [];
  336. for (var p = promise; !!p; p = p.source) {
  337. if (p.stack) {
  338. stacks.unshift(p.stack);
  339. }
  340. }
  341. stacks.unshift(error.stack);
  342. var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
  343. error.stack = filterStackString(concatedStacks);
  344. }
  345. }
  346. function filterStackString(stackString) {
  347. var lines = stackString.split("\n");
  348. var desiredLines = [];
  349. for (var i = 0; i < lines.length; ++i) {
  350. var line = lines[i];
  351. if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
  352. desiredLines.push(line);
  353. }
  354. }
  355. return desiredLines.join("\n");
  356. }
  357. function isNodeFrame(stackLine) {
  358. return stackLine.indexOf("(module.js:") !== -1 ||
  359. stackLine.indexOf("(node.js:") !== -1;
  360. }
  361. function getFileNameAndLineNumber(stackLine) {
  362. // Named functions: "at functionName (filename:lineNumber:columnNumber)"
  363. // In IE10 function name can have spaces ("Anonymous function") O_o
  364. var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
  365. if (attempt1) {
  366. return [attempt1[1], Number(attempt1[2])];
  367. }
  368. // Anonymous functions: "at filename:lineNumber:columnNumber"
  369. var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
  370. if (attempt2) {
  371. return [attempt2[1], Number(attempt2[2])];
  372. }
  373. // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
  374. var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
  375. if (attempt3) {
  376. return [attempt3[1], Number(attempt3[2])];
  377. }
  378. }
  379. function isInternalFrame(stackLine) {
  380. var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
  381. if (!fileNameAndLineNumber) {
  382. return false;
  383. }
  384. var fileName = fileNameAndLineNumber[0];
  385. var lineNumber = fileNameAndLineNumber[1];
  386. return fileName === qFileName &&
  387. lineNumber >= qStartingLine &&
  388. lineNumber <= qEndingLine;
  389. }
  390. // discover own file name and line number range for filtering stack
  391. // traces
  392. function captureLine() {
  393. if (!hasStacks) {
  394. return;
  395. }
  396. try {
  397. throw new Error();
  398. } catch (e) {
  399. var lines = e.stack.split("\n");
  400. var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
  401. var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
  402. if (!fileNameAndLineNumber) {
  403. return;
  404. }
  405. qFileName = fileNameAndLineNumber[0];
  406. return fileNameAndLineNumber[1];
  407. }
  408. }
  409. function deprecate(callback, name, alternative) {
  410. return function () {
  411. if (typeof console !== "undefined" &&
  412. typeof console.warn === "function") {
  413. console.warn(name + " is deprecated, use " + alternative +
  414. " instead.", new Error("").stack);
  415. }
  416. return callback.apply(callback, arguments);
  417. };
  418. }
  419. // end of shims
  420. // beginning of real work
  421. /**
  422. * Constructs a promise for an immediate reference, passes promises through, or
  423. * coerces promises from different systems.
  424. * @param value immediate reference or promise
  425. */
  426. function Q(value) {
  427. // If the object is already a Promise, return it directly. This enables
  428. // the resolve function to both be used to created references from objects,
  429. // but to tolerably coerce non-promises to promises.
  430. if (value instanceof Promise) {
  431. return value;
  432. }
  433. // assimilate thenables
  434. if (isPromiseAlike(value)) {
  435. return coerce(value);
  436. } else {
  437. return fulfill(value);
  438. }
  439. }
  440. Q.resolve = Q;
  441. /**
  442. * Performs a task in a future turn of the event loop.
  443. * @param {Function} task
  444. */
  445. Q.nextTick = nextTick;
  446. /**
  447. * Controls whether or not long stack traces will be on
  448. */
  449. Q.longStackSupport = false;
  450. // enable long stacks if Q_DEBUG is set
  451. if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
  452. Q.longStackSupport = true;
  453. }
  454. /**
  455. * Constructs a {promise, resolve, reject} object.
  456. *
  457. * `resolve` is a callback to invoke with a more resolved value for the
  458. * promise. To fulfill the promise, invoke `resolve` with any value that is
  459. * not a thenable. To reject the promise, invoke `resolve` with a rejected
  460. * thenable, or invoke `reject` with the reason directly. To resolve the
  461. * promise to another thenable, thus putting it in the same state, invoke
  462. * `resolve` with that other thenable.
  463. */
  464. Q.defer = defer;
  465. function defer() {
  466. // if "messages" is an "Array", that indicates that the promise has not yet
  467. // been resolved. If it is "undefined", it has been resolved. Each
  468. // element of the messages array is itself an array of complete arguments to
  469. // forward to the resolved promise. We coerce the resolution value to a
  470. // promise using the `resolve` function because it handles both fully
  471. // non-thenable values and other thenables gracefully.
  472. var messages = [], progressListeners = [], resolvedPromise;
  473. var deferred = object_create(defer.prototype);
  474. var promise = object_create(Promise.prototype);
  475. promise.promiseDispatch = function (resolve, op, operands) {
  476. var args = array_slice(arguments);
  477. if (messages) {
  478. messages.push(args);
  479. if (op === "when" && operands[1]) { // progress operand
  480. progressListeners.push(operands[1]);
  481. }
  482. } else {
  483. Q.nextTick(function () {
  484. resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
  485. });
  486. }
  487. };
  488. // XXX deprecated
  489. promise.valueOf = function () {
  490. if (messages) {
  491. return promise;
  492. }
  493. var nearerValue = nearer(resolvedPromise);
  494. if (isPromise(nearerValue)) {
  495. resolvedPromise = nearerValue; // shorten chain
  496. }
  497. return nearerValue;
  498. };
  499. promise.inspect = function () {
  500. if (!resolvedPromise) {
  501. return { state: "pending" };
  502. }
  503. return resolvedPromise.inspect();
  504. };
  505. if (Q.longStackSupport && hasStacks) {
  506. try {
  507. throw new Error();
  508. } catch (e) {
  509. // NOTE: don't try to use `Error.captureStackTrace` or transfer the
  510. // accessor around; that causes memory leaks as per GH-111. Just
  511. // reify the stack trace as a string ASAP.
  512. //
  513. // At the same time, cut off the first line; it's always just
  514. // "[object Promise]\n", as per the `toString`.
  515. promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
  516. }
  517. }
  518. // NOTE: we do the checks for `resolvedPromise` in each method, instead of
  519. // consolidating them into `become`, since otherwise we'd create new
  520. // promises with the lines `become(whatever(value))`. See e.g. GH-252.
  521. function become(newPromise) {
  522. resolvedPromise = newPromise;
  523. promise.source = newPromise;
  524. array_reduce(messages, function (undefined, message) {
  525. Q.nextTick(function () {
  526. newPromise.promiseDispatch.apply(newPromise, message);
  527. });
  528. }, void 0);
  529. messages = void 0;
  530. progressListeners = void 0;
  531. }
  532. deferred.promise = promise;
  533. deferred.resolve = function (value) {
  534. if (resolvedPromise) {
  535. return;
  536. }
  537. become(Q(value));
  538. };
  539. deferred.fulfill = function (value) {
  540. if (resolvedPromise) {
  541. return;
  542. }
  543. become(fulfill(value));
  544. };
  545. deferred.reject = function (reason) {
  546. if (resolvedPromise) {
  547. return;
  548. }
  549. become(reject(reason));
  550. };
  551. deferred.notify = function (progress) {
  552. if (resolvedPromise) {
  553. return;
  554. }
  555. array_reduce(progressListeners, function (undefined, progressListener) {
  556. Q.nextTick(function () {
  557. progressListener(progress);
  558. });
  559. }, void 0);
  560. };
  561. return deferred;
  562. }
  563. /**
  564. * Creates a Node-style callback that will resolve or reject the deferred
  565. * promise.
  566. * @returns a nodeback
  567. */
  568. defer.prototype.makeNodeResolver = function () {
  569. var self = this;
  570. return function (error, value) {
  571. if (error) {
  572. self.reject(error);
  573. } else if (arguments.length > 2) {
  574. self.resolve(array_slice(arguments, 1));
  575. } else {
  576. self.resolve(value);
  577. }
  578. };
  579. };
  580. /**
  581. * @param resolver {Function} a function that returns nothing and accepts
  582. * the resolve, reject, and notify functions for a deferred.
  583. * @returns a promise that may be resolved with the given resolve and reject
  584. * functions, or rejected by a thrown exception in resolver
  585. */
  586. Q.Promise = promise; // ES6
  587. Q.promise = promise;
  588. function promise(resolver) {
  589. if (typeof resolver !== "function") {
  590. throw new TypeError("resolver must be a function.");
  591. }
  592. var deferred = defer();
  593. try {
  594. resolver(deferred.resolve, deferred.reject, deferred.notify);
  595. } catch (reason) {
  596. deferred.reject(reason);
  597. }
  598. return deferred.promise;
  599. }
  600. promise.race = race; // ES6
  601. promise.all = all; // ES6
  602. promise.reject = reject; // ES6
  603. promise.resolve = Q; // ES6
  604. // XXX experimental. This method is a way to denote that a local value is
  605. // serializable and should be immediately dispatched to a remote upon request,
  606. // instead of passing a reference.
  607. Q.passByCopy = function (object) {
  608. //freeze(object);
  609. //passByCopies.set(object, true);
  610. return object;
  611. };
  612. Promise.prototype.passByCopy = function () {
  613. //freeze(object);
  614. //passByCopies.set(object, true);
  615. return this;
  616. };
  617. /**
  618. * If two promises eventually fulfill to the same value, promises that value,
  619. * but otherwise rejects.
  620. * @param x {Any*}
  621. * @param y {Any*}
  622. * @returns {Any*} a promise for x and y if they are the same, but a rejection
  623. * otherwise.
  624. *
  625. */
  626. Q.join = function (x, y) {
  627. return Q(x).join(y);
  628. };
  629. Promise.prototype.join = function (that) {
  630. return Q([this, that]).spread(function (x, y) {
  631. if (x === y) {
  632. // TODO: "===" should be Object.is or equiv
  633. return x;
  634. } else {
  635. throw new Error("Can't join: not the same: " + x + " " + y);
  636. }
  637. });
  638. };
  639. /**
  640. * Returns a promise for the first of an array of promises to become settled.
  641. * @param answers {Array[Any*]} promises to race
  642. * @returns {Any*} the first promise to be settled
  643. */
  644. Q.race = race;
  645. function race(answerPs) {
  646. return promise(function (resolve, reject) {
  647. // Switch to this once we can assume at least ES5
  648. // answerPs.forEach(function (answerP) {
  649. // Q(answerP).then(resolve, reject);
  650. // });
  651. // Use this in the meantime
  652. for (var i = 0, len = answerPs.length; i < len; i++) {
  653. Q(answerPs[i]).then(resolve, reject);
  654. }
  655. });
  656. }
  657. Promise.prototype.race = function () {
  658. return this.then(Q.race);
  659. };
  660. /**
  661. * Constructs a Promise with a promise descriptor object and optional fallback
  662. * function. The descriptor contains methods like when(rejected), get(name),
  663. * set(name, value), post(name, args), and delete(name), which all
  664. * return either a value, a promise for a value, or a rejection. The fallback
  665. * accepts the operation name, a resolver, and any further arguments that would
  666. * have been forwarded to the appropriate method above had a method been
  667. * provided with the proper name. The API makes no guarantees about the nature
  668. * of the returned object, apart from that it is usable whereever promises are
  669. * bought and sold.
  670. */
  671. Q.makePromise = Promise;
  672. function Promise(descriptor, fallback, inspect) {
  673. if (fallback === void 0) {
  674. fallback = function (op) {
  675. return reject(new Error(
  676. "Promise does not support operation: " + op
  677. ));
  678. };
  679. }
  680. if (inspect === void 0) {
  681. inspect = function () {
  682. return {state: "unknown"};
  683. };
  684. }
  685. var promise = object_create(Promise.prototype);
  686. promise.promiseDispatch = function (resolve, op, args) {
  687. var result;
  688. try {
  689. if (descriptor[op]) {
  690. result = descriptor[op].apply(promise, args);
  691. } else {
  692. result = fallback.call(promise, op, args);
  693. }
  694. } catch (exception) {
  695. result = reject(exception);
  696. }
  697. if (resolve) {
  698. resolve(result);
  699. }
  700. };
  701. promise.inspect = inspect;
  702. // XXX deprecated `valueOf` and `exception` support
  703. if (inspect) {
  704. var inspected = inspect();
  705. if (inspected.state === "rejected") {
  706. promise.exception = inspected.reason;
  707. }
  708. promise.valueOf = function () {
  709. var inspected = inspect();
  710. if (inspected.state === "pending" ||
  711. inspected.state === "rejected") {
  712. return promise;
  713. }
  714. return inspected.value;
  715. };
  716. }
  717. return promise;
  718. }
  719. Promise.prototype.toString = function () {
  720. return "[object Promise]";
  721. };
  722. Promise.prototype.then = function (fulfilled, rejected, progressed) {
  723. var self = this;
  724. var deferred = defer();
  725. var done = false; // ensure the untrusted promise makes at most a
  726. // single call to one of the callbacks
  727. function _fulfilled(value) {
  728. try {
  729. return typeof fulfilled === "function" ? fulfilled(value) : value;
  730. } catch (exception) {
  731. return reject(exception);
  732. }
  733. }
  734. function _rejected(exception) {
  735. if (typeof rejected === "function") {
  736. makeStackTraceLong(exception, self);
  737. try {
  738. return rejected(exception);
  739. } catch (newException) {
  740. return reject(newException);
  741. }
  742. }
  743. return reject(exception);
  744. }
  745. function _progressed(value) {
  746. return typeof progressed === "function" ? progressed(value) : value;
  747. }
  748. Q.nextTick(function () {
  749. self.promiseDispatch(function (value) {
  750. if (done) {
  751. return;
  752. }
  753. done = true;
  754. deferred.resolve(_fulfilled(value));
  755. }, "when", [function (exception) {
  756. if (done) {
  757. return;
  758. }
  759. done = true;
  760. deferred.resolve(_rejected(exception));
  761. }]);
  762. });
  763. // Progress propagator need to be attached in the current tick.
  764. self.promiseDispatch(void 0, "when", [void 0, function (value) {
  765. var newValue;
  766. var threw = false;
  767. try {
  768. newValue = _progressed(value);
  769. } catch (e) {
  770. threw = true;
  771. if (Q.onerror) {
  772. Q.onerror(e);
  773. } else {
  774. throw e;
  775. }
  776. }
  777. if (!threw) {
  778. deferred.notify(newValue);
  779. }
  780. }]);
  781. return deferred.promise;
  782. };
  783. Q.tap = function (promise, callback) {
  784. return Q(promise).tap(callback);
  785. };
  786. /**
  787. * Works almost like "finally", but not called for rejections.
  788. * Original resolution value is passed through callback unaffected.
  789. * Callback may return a promise that will be awaited for.
  790. * @param {Function} callback
  791. * @returns {Q.Promise}
  792. * @example
  793. * doSomething()
  794. * .then(...)
  795. * .tap(console.log)
  796. * .then(...);
  797. */
  798. Promise.prototype.tap = function (callback) {
  799. callback = Q(callback);
  800. return this.then(function (value) {
  801. return callback.fcall(value).thenResolve(value);
  802. });
  803. };
  804. /**
  805. * Registers an observer on a promise.
  806. *
  807. * Guarantees:
  808. *
  809. * 1. that fulfilled and rejected will be called only once.
  810. * 2. that either the fulfilled callback or the rejected callback will be
  811. * called, but not both.
  812. * 3. that fulfilled and rejected will not be called in this turn.
  813. *
  814. * @param value promise or immediate reference to observe
  815. * @param fulfilled function to be called with the fulfilled value
  816. * @param rejected function to be called with the rejection exception
  817. * @param progressed function to be called on any progress notifications
  818. * @return promise for the return value from the invoked callback
  819. */
  820. Q.when = when;
  821. function when(value, fulfilled, rejected, progressed) {
  822. return Q(value).then(fulfilled, rejected, progressed);
  823. }
  824. Promise.prototype.thenResolve = function (value) {
  825. return this.then(function () { return value; });
  826. };
  827. Q.thenResolve = function (promise, value) {
  828. return Q(promise).thenResolve(value);
  829. };
  830. Promise.prototype.thenReject = function (reason) {
  831. return this.then(function () { throw reason; });
  832. };
  833. Q.thenReject = function (promise, reason) {
  834. return Q(promise).thenReject(reason);
  835. };
  836. /**
  837. * If an object is not a promise, it is as "near" as possible.
  838. * If a promise is rejected, it is as "near" as possible too.
  839. * If it’s a fulfilled promise, the fulfillment value is nearer.
  840. * If it’s a deferred promise and the deferred has been resolved, the
  841. * resolution is "nearer".
  842. * @param object
  843. * @returns most resolved (nearest) form of the object
  844. */
  845. // XXX should we re-do this?
  846. Q.nearer = nearer;
  847. function nearer(value) {
  848. if (isPromise(value)) {
  849. var inspected = value.inspect();
  850. if (inspected.state === "fulfilled") {
  851. return inspected.value;
  852. }
  853. }
  854. return value;
  855. }
  856. /**
  857. * @returns whether the given object is a promise.
  858. * Otherwise it is a fulfilled value.
  859. */
  860. Q.isPromise = isPromise;
  861. function isPromise(object) {
  862. return object instanceof Promise;
  863. }
  864. Q.isPromiseAlike = isPromiseAlike;
  865. function isPromiseAlike(object) {
  866. return isObject(object) && typeof object.then === "function";
  867. }
  868. /**
  869. * @returns whether the given object is a pending promise, meaning not
  870. * fulfilled or rejected.
  871. */
  872. Q.isPending = isPending;
  873. function isPending(object) {
  874. return isPromise(object) && object.inspect().state === "pending";
  875. }
  876. Promise.prototype.isPending = function () {
  877. return this.inspect().state === "pending";
  878. };
  879. /**
  880. * @returns whether the given object is a value or fulfilled
  881. * promise.
  882. */
  883. Q.isFulfilled = isFulfilled;
  884. function isFulfilled(object) {
  885. return !isPromise(object) || object.inspect().state === "fulfilled";
  886. }
  887. Promise.prototype.isFulfilled = function () {
  888. return this.inspect().state === "fulfilled";
  889. };
  890. /**
  891. * @returns whether the given object is a rejected promise.
  892. */
  893. Q.isRejected = isRejected;
  894. function isRejected(object) {
  895. return isPromise(object) && object.inspect().state === "rejected";
  896. }
  897. Promise.prototype.isRejected = function () {
  898. return this.inspect().state === "rejected";
  899. };
  900. //// BEGIN UNHANDLED REJECTION TRACKING
  901. // This promise library consumes exceptions thrown in handlers so they can be
  902. // handled by a subsequent promise. The exceptions get added to this array when
  903. // they are created, and removed when they are handled. Note that in ES6 or
  904. // shimmed environments, this would naturally be a `Set`.
  905. var unhandledReasons = [];
  906. var unhandledRejections = [];
  907. var reportedUnhandledRejections = [];
  908. var trackUnhandledRejections = true;
  909. function resetUnhandledRejections() {
  910. unhandledReasons.length = 0;
  911. unhandledRejections.length = 0;
  912. if (!trackUnhandledRejections) {
  913. trackUnhandledRejections = true;
  914. }
  915. }
  916. function trackRejection(promise, reason) {
  917. if (!trackUnhandledRejections) {
  918. return;
  919. }
  920. if (typeof process === "object" && typeof process.emit === "function") {
  921. Q.nextTick.runAfter(function () {
  922. if (array_indexOf(unhandledRejections, promise) !== -1) {
  923. process.emit("unhandledRejection", reason, promise);
  924. reportedUnhandledRejections.push(promise);
  925. }
  926. });
  927. }
  928. unhandledRejections.push(promise);
  929. if (reason && typeof reason.stack !== "undefined") {
  930. unhandledReasons.push(reason.stack);
  931. } else {
  932. unhandledReasons.push("(no stack) " + reason);
  933. }
  934. }
  935. function untrackRejection(promise) {
  936. if (!trackUnhandledRejections) {
  937. return;
  938. }
  939. var at = array_indexOf(unhandledRejections, promise);
  940. if (at !== -1) {
  941. if (typeof process === "object" && typeof process.emit === "function") {
  942. Q.nextTick.runAfter(function () {
  943. var atReport = array_indexOf(reportedUnhandledRejections, promise);
  944. if (atReport !== -1) {
  945. process.emit("rejectionHandled", unhandledReasons[at], promise);
  946. reportedUnhandledRejections.splice(atReport, 1);
  947. }
  948. });
  949. }
  950. unhandledRejections.splice(at, 1);
  951. unhandledReasons.splice(at, 1);
  952. }
  953. }
  954. Q.resetUnhandledRejections = resetUnhandledRejections;
  955. Q.getUnhandledReasons = function () {
  956. // Make a copy so that consumers can't interfere with our internal state.
  957. return unhandledReasons.slice();
  958. };
  959. Q.stopUnhandledRejectionTracking = function () {
  960. resetUnhandledRejections();
  961. trackUnhandledRejections = false;
  962. };
  963. resetUnhandledRejections();
  964. //// END UNHANDLED REJECTION TRACKING
  965. /**
  966. * Constructs a rejected promise.
  967. * @param reason value describing the failure
  968. */
  969. Q.reject = reject;
  970. function reject(reason) {
  971. var rejection = Promise({
  972. "when": function (rejected) {
  973. // note that the error has been handled
  974. if (rejected) {
  975. untrackRejection(this);
  976. }
  977. return rejected ? rejected(reason) : this;
  978. }
  979. }, function fallback() {
  980. return this;
  981. }, function inspect() {
  982. return { state: "rejected", reason: reason };
  983. });
  984. // Note that the reason has not been handled.
  985. trackRejection(rejection, reason);
  986. return rejection;
  987. }
  988. /**
  989. * Constructs a fulfilled promise for an immediate reference.
  990. * @param value immediate reference
  991. */
  992. Q.fulfill = fulfill;
  993. function fulfill(value) {
  994. return Promise({
  995. "when": function () {
  996. return value;
  997. },
  998. "get": function (name) {
  999. return value[name];
  1000. },
  1001. "set": function (name, rhs) {
  1002. value[name] = rhs;
  1003. },
  1004. "delete": function (name) {
  1005. delete value[name];
  1006. },
  1007. "post": function (name, args) {
  1008. // Mark Miller proposes that post with no name should apply a
  1009. // promised function.
  1010. if (name === null || name === void 0) {
  1011. return value.apply(void 0, args);
  1012. } else {
  1013. return value[name].apply(value, args);
  1014. }
  1015. },
  1016. "apply": function (thisp, args) {
  1017. return value.apply(thisp, args);
  1018. },
  1019. "keys": function () {
  1020. return object_keys(value);
  1021. }
  1022. }, void 0, function inspect() {
  1023. return { state: "fulfilled", value: value };
  1024. });
  1025. }
  1026. /**
  1027. * Converts thenables to Q promises.
  1028. * @param promise thenable promise
  1029. * @returns a Q promise
  1030. */
  1031. function coerce(promise) {
  1032. var deferred = defer();
  1033. Q.nextTick(function () {
  1034. try {
  1035. promise.then(deferred.resolve, deferred.reject, deferred.notify);
  1036. } catch (exception) {
  1037. deferred.reject(exception);
  1038. }
  1039. });
  1040. return deferred.promise;
  1041. }
  1042. /**
  1043. * Annotates an object such that it will never be
  1044. * transferred away from this process over any promise
  1045. * communication channel.
  1046. * @param object
  1047. * @returns promise a wrapping of that object that
  1048. * additionally responds to the "isDef" message
  1049. * without a rejection.
  1050. */
  1051. Q.master = master;
  1052. function master(object) {
  1053. return Promise({
  1054. "isDef": function () {}
  1055. }, function fallback(op, args) {
  1056. return dispatch(object, op, args);
  1057. }, function () {
  1058. return Q(object).inspect();
  1059. });
  1060. }
  1061. /**
  1062. * Spreads the values of a promised array of arguments into the
  1063. * fulfillment callback.
  1064. * @param fulfilled callback that receives variadic arguments from the
  1065. * promised array
  1066. * @param rejected callback that receives the exception if the promise
  1067. * is rejected.
  1068. * @returns a promise for the return value or thrown exception of
  1069. * either callback.
  1070. */
  1071. Q.spread = spread;
  1072. function spread(value, fulfilled, rejected) {
  1073. return Q(value).spread(fulfilled, rejected);
  1074. }
  1075. Promise.prototype.spread = function (fulfilled, rejected) {
  1076. return this.all().then(function (array) {
  1077. return fulfilled.apply(void 0, array);
  1078. }, rejected);
  1079. };
  1080. /**
  1081. * The async function is a decorator for generator functions, turning
  1082. * them into asynchronous generators. Although generators are only part
  1083. * of the newest ECMAScript 6 drafts, this code does not cause syntax
  1084. * errors in older engines. This code should continue to work and will
  1085. * in fact improve over time as the language improves.
  1086. *
  1087. * ES6 generators are currently part of V8 version 3.19 with the
  1088. * --harmony-generators runtime flag enabled. SpiderMonkey has had them
  1089. * for longer, but under an older Python-inspired form. This function
  1090. * works on both kinds of generators.
  1091. *
  1092. * Decorates a generator function such that:
  1093. * - it may yield promises
  1094. * - execution will continue when that promise is fulfilled
  1095. * - the value of the yield expression will be the fulfilled value
  1096. * - it returns a promise for the return value (when the generator
  1097. * stops iterating)
  1098. * - the decorated function returns a promise for the return value
  1099. * of the generator or the first rejected promise among those
  1100. * yielded.
  1101. * - if an error is thrown in the generator, it propagates through
  1102. * every following yield until it is caught, or until it escapes
  1103. * the generator function altogether, and is translated into a
  1104. * rejection for the promise returned by the decorated generator.
  1105. */
  1106. Q.async = async;
  1107. function async(makeGenerator) {
  1108. return function () {
  1109. // when verb is "send", arg is a value
  1110. // when verb is "throw", arg is an exception
  1111. function continuer(verb, arg) {
  1112. var result;
  1113. // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
  1114. // engine that has a deployed base of browsers that support generators.
  1115. // However, SM's generators use the Python-inspired semantics of
  1116. // outdated ES6 drafts. We would like to support ES6, but we'd also
  1117. // like to make it possible to use generators in deployed browsers, so
  1118. // we also support Python-style generators. At some point we can remove
  1119. // this block.
  1120. if (typeof StopIteration === "undefined") {
  1121. // ES6 Generators
  1122. try {
  1123. result = generator[verb](arg);
  1124. } catch (exception) {
  1125. return reject(exception);
  1126. }
  1127. if (result.done) {
  1128. return Q(result.value);
  1129. } else {
  1130. return when(result.value, callback, errback);
  1131. }
  1132. } else {
  1133. // SpiderMonkey Generators
  1134. // FIXME: Remove this case when SM does ES6 generators.
  1135. try {
  1136. result = generator[verb](arg);
  1137. } catch (exception) {
  1138. if (isStopIteration(exception)) {
  1139. return Q(exception.value);
  1140. } else {
  1141. return reject(exception);
  1142. }
  1143. }
  1144. return when(result, callback, errback);
  1145. }
  1146. }
  1147. var generator = makeGenerator.apply(this, arguments);
  1148. var callback = continuer.bind(continuer, "next");
  1149. var errback = continuer.bind(continuer, "throw");
  1150. return callback();
  1151. };
  1152. }
  1153. /**
  1154. * The spawn function is a small wrapper around async that immediately
  1155. * calls the generator and also ends the promise chain, so that any
  1156. * unhandled errors are thrown instead of forwarded to the error
  1157. * handler. This is useful because it's extremely common to run
  1158. * generators at the top-level to work with libraries.
  1159. */
  1160. Q.spawn = spawn;
  1161. function spawn(makeGenerator) {
  1162. Q.done(Q.async(makeGenerator)());
  1163. }
  1164. // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
  1165. /**
  1166. * Throws a ReturnValue exception to stop an asynchronous generator.
  1167. *
  1168. * This interface is a stop-gap measure to support generator return
  1169. * values in older Firefox/SpiderMonkey. In browsers that support ES6
  1170. * generators like Chromium 29, just use "return" in your generator
  1171. * functions.
  1172. *
  1173. * @param value the return value for the surrounding generator
  1174. * @throws ReturnValue exception with the value.
  1175. * @example
  1176. * // ES6 style
  1177. * Q.async(function* () {
  1178. * var foo = yield getFooPromise();
  1179. * var bar = yield getBarPromise();
  1180. * return foo + bar;
  1181. * })
  1182. * // Older SpiderMonkey style
  1183. * Q.async(function () {
  1184. * var foo = yield getFooPromise();
  1185. * var bar = yield getBarPromise();
  1186. * Q.return(foo + bar);
  1187. * })
  1188. */
  1189. Q["return"] = _return;
  1190. function _return(value) {
  1191. throw new QReturnValue(value);
  1192. }
  1193. /**
  1194. * The promised function decorator ensures that any promise arguments
  1195. * are settled and passed as values (`this` is also settled and passed
  1196. * as a value). It will also ensure that the result of a function is
  1197. * always a promise.
  1198. *
  1199. * @example
  1200. * var add = Q.promised(function (a, b) {
  1201. * return a + b;
  1202. * });
  1203. * add(Q(a), Q(B));
  1204. *
  1205. * @param {function} callback The function to decorate
  1206. * @returns {function} a function that has been decorated.
  1207. */
  1208. Q.promised = promised;
  1209. function promised(callback) {
  1210. return function () {
  1211. return spread([this, all(arguments)], function (self, args) {
  1212. return callback.apply(self, args);
  1213. });
  1214. };
  1215. }
  1216. /**
  1217. * sends a message to a value in a future turn
  1218. * @param object* the recipient
  1219. * @param op the name of the message operation, e.g., "when",
  1220. * @param args further arguments to be forwarded to the operation
  1221. * @returns result {Promise} a promise for the result of the operation
  1222. */
  1223. Q.dispatch = dispatch;
  1224. function dispatch(object, op, args) {
  1225. return Q(object).dispatch(op, args);
  1226. }
  1227. Promise.prototype.dispatch = function (op, args) {
  1228. var self = this;
  1229. var deferred = defer();
  1230. Q.nextTick(function () {
  1231. self.promiseDispatch(deferred.resolve, op, args);
  1232. });
  1233. return deferred.promise;
  1234. };
  1235. /**
  1236. * Gets the value of a property in a future turn.
  1237. * @param object promise or immediate reference for target object
  1238. * @param name name of property to get
  1239. * @return promise for the property value
  1240. */
  1241. Q.get = function (object, key) {
  1242. return Q(object).dispatch("get", [key]);
  1243. };
  1244. Promise.prototype.get = function (key) {
  1245. return this.dispatch("get", [key]);
  1246. };
  1247. /**
  1248. * Sets the value of a property in a future turn.
  1249. * @param object promise or immediate reference for object object
  1250. * @param name name of property to set
  1251. * @param value new value of property
  1252. * @return promise for the return value
  1253. */
  1254. Q.set = function (object, key, value) {
  1255. return Q(object).dispatch("set", [key, value]);
  1256. };
  1257. Promise.prototype.set = function (key, value) {
  1258. return this.dispatch("set", [key, value]);
  1259. };
  1260. /**
  1261. * Deletes a property in a future turn.
  1262. * @param object promise or immediate reference for target object
  1263. * @param name name of property to delete
  1264. * @return promise for the return value
  1265. */
  1266. Q.del = // XXX legacy
  1267. Q["delete"] = function (object, key) {
  1268. return Q(object).dispatch("delete", [key]);
  1269. };
  1270. Promise.prototype.del = // XXX legacy
  1271. Promise.prototype["delete"] = function (key) {
  1272. return this.dispatch("delete", [key]);
  1273. };
  1274. /**
  1275. * Invokes a method in a future turn.
  1276. * @param object promise or immediate reference for target object
  1277. * @param name name of method to invoke
  1278. * @param value a value to post, typically an array of
  1279. * invocation arguments for promises that
  1280. * are ultimately backed with `resolve` values,
  1281. * as opposed to those backed with URLs
  1282. * wherein the posted value can be any
  1283. * JSON serializable object.
  1284. * @return promise for the return value
  1285. */
  1286. // bound locally because it is used by other methods
  1287. Q.mapply = // XXX As proposed by "Redsandro"
  1288. Q.post = function (object, name, args) {
  1289. return Q(object).dispatch("post", [name, args]);
  1290. };
  1291. Promise.prototype.mapply = // XXX As proposed by "Redsandro"
  1292. Promise.prototype.post = function (name, args) {
  1293. return this.dispatch("post", [name, args]);
  1294. };
  1295. /**
  1296. * Invokes a method in a future turn.
  1297. * @param object promise or immediate reference for target object
  1298. * @param name name of method to invoke
  1299. * @param ...args array of invocation arguments
  1300. * @return promise for the return value
  1301. */
  1302. Q.send = // XXX Mark Miller's proposed parlance
  1303. Q.mcall = // XXX As proposed by "Redsandro"
  1304. Q.invoke = function (object, name /*...args*/) {
  1305. return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
  1306. };
  1307. Promise.prototype.send = // XXX Mark Miller's proposed parlance
  1308. Promise.prototype.mcall = // XXX As proposed by "Redsandro"
  1309. Promise.prototype.invoke = function (name /*...args*/) {
  1310. return this.dispatch("post", [name, array_slice(arguments, 1)]);
  1311. };
  1312. /**
  1313. * Applies the promised function in a future turn.
  1314. * @param object promise or immediate reference for target function
  1315. * @param args array of application arguments
  1316. */
  1317. Q.fapply = function (object, args) {
  1318. return Q(object).dispatch("apply", [void 0, args]);
  1319. };
  1320. Promise.prototype.fapply = function (args) {
  1321. return this.dispatch("apply", [void 0, args]);
  1322. };
  1323. /**
  1324. * Calls the promised function in a future turn.
  1325. * @param object promise or immediate reference for target function
  1326. * @param ...args array of application arguments
  1327. */
  1328. Q["try"] =
  1329. Q.fcall = function (object /* ...args*/) {
  1330. return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
  1331. };
  1332. Promise.prototype.fcall = function (/*...args*/) {
  1333. return this.dispatch("apply", [void 0, array_slice(arguments)]);
  1334. };
  1335. /**
  1336. * Binds the promised function, transforming return values into a fulfilled
  1337. * promise and thrown errors into a rejected one.
  1338. * @param object promise or immediate reference for target function
  1339. * @param ...args array of application arguments
  1340. */
  1341. Q.fbind = function (object /*...args*/) {
  1342. var promise = Q(object);
  1343. var args = array_slice(arguments, 1);
  1344. return function fbound() {
  1345. return promise.dispatch("apply", [
  1346. this,
  1347. args.concat(array_slice(arguments))
  1348. ]);
  1349. };
  1350. };
  1351. Promise.prototype.fbind = function (/*...args*/) {
  1352. var promise = this;
  1353. var args = array_slice(arguments);
  1354. return function fbound() {
  1355. return promise.dispatch("apply", [
  1356. this,
  1357. args.concat(array_slice(arguments))
  1358. ]);
  1359. };
  1360. };
  1361. /**
  1362. * Requests the names of the owned properties of a promised
  1363. * object in a future turn.
  1364. * @param object promise or immediate reference for target object
  1365. * @return promise for the keys of the eventually settled object
  1366. */
  1367. Q.keys = function (object) {
  1368. return Q(object).dispatch("keys", []);
  1369. };
  1370. Promise.prototype.keys = function () {
  1371. return this.dispatch("keys", []);
  1372. };
  1373. /**
  1374. * Turns an array of promises into a promise for an array. If any of
  1375. * the promises gets rejected, the whole array is rejected immediately.
  1376. * @param {Array*} an array (or promise for an array) of values (or
  1377. * promises for values)
  1378. * @returns a promise for an array of the corresponding values
  1379. */
  1380. // By Mark Miller
  1381. // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
  1382. Q.all = all;
  1383. function all(promises) {
  1384. return when(promises, function (promises) {
  1385. var pendingCount = 0;
  1386. var deferred = defer();
  1387. array_reduce(promises, function (undefined, promise, index) {
  1388. var snapshot;
  1389. if (
  1390. isPromise(promise) &&
  1391. (snapshot = promise.inspect()).state === "fulfilled"
  1392. ) {
  1393. promises[index] = snapshot.value;
  1394. } else {
  1395. ++pendingCount;
  1396. when(
  1397. promise,
  1398. function (value) {
  1399. promises[index] = value;
  1400. if (--pendingCount === 0) {
  1401. deferred.resolve(promises);
  1402. }
  1403. },
  1404. deferred.reject,
  1405. function (progress) {
  1406. deferred.notify({ index: index, value: progress });
  1407. }
  1408. );
  1409. }
  1410. }, void 0);
  1411. if (pendingCount === 0) {
  1412. deferred.resolve(promises);
  1413. }
  1414. return deferred.promise;
  1415. });
  1416. }
  1417. Promise.prototype.all = function () {
  1418. return all(this);
  1419. };
  1420. /**
  1421. * Returns the first resolved promise of an array. Prior rejected promises are
  1422. * ignored. Rejects only if all promises are rejected.
  1423. * @param {Array*} an array containing values or promises for values
  1424. * @returns a promise fulfilled with the value of the first resolved promise,
  1425. * or a rejected promise if all promises are rejected.
  1426. */
  1427. Q.any = any;
  1428. function any(promises) {
  1429. if (promises.length === 0) {
  1430. return Q.resolve();
  1431. }
  1432. var deferred = Q.defer();
  1433. var pendingCount = 0;
  1434. array_reduce(promises, function (prev, current, index) {
  1435. var promise = promises[index];
  1436. pendingCount++;
  1437. when(promise, onFulfilled, onRejected, onProgress);
  1438. function onFulfilled(result) {
  1439. deferred.resolve(result);
  1440. }
  1441. function onRejected() {
  1442. pendingCount--;
  1443. if (pendingCount === 0) {
  1444. deferred.reject(new Error(
  1445. "Can't get fulfillment value from any promise, all " +
  1446. "promises were rejected."
  1447. ));
  1448. }
  1449. }
  1450. function onProgress(progress) {
  1451. deferred.notify({
  1452. index: index,
  1453. value: progress
  1454. });
  1455. }
  1456. }, undefined);
  1457. return deferred.promise;
  1458. }
  1459. Promise.prototype.any = function () {
  1460. return any(this);
  1461. };
  1462. /**
  1463. * Waits for all promises to be settled, either fulfilled or
  1464. * rejected. This is distinct from `all` since that would stop
  1465. * waiting at the first rejection. The promise returned by
  1466. * `allResolved` will never be rejected.
  1467. * @param promises a promise for an array (or an array) of promises
  1468. * (or values)
  1469. * @return a promise for an array of promises
  1470. */
  1471. Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
  1472. function allResolved(promises) {
  1473. return when(promises, function (promises) {
  1474. promises = array_map(promises, Q);
  1475. return when(all(array_map(promises, function (promise) {
  1476. return when(promise, noop, noop);
  1477. })), function () {
  1478. return promises;
  1479. });
  1480. });
  1481. }
  1482. Promise.prototype.allResolved = function () {
  1483. return allResolved(this);
  1484. };
  1485. /**
  1486. * @see Promise#allSettled
  1487. */
  1488. Q.allSettled = allSettled;
  1489. function allSettled(promises) {
  1490. return Q(promises).allSettled();
  1491. }
  1492. /**
  1493. * Turns an array of promises into a promise for an array of their states (as
  1494. * returned by `inspect`) when they have all settled.
  1495. * @param {Array[Any*]} values an array (or promise for an array) of values (or
  1496. * promises for values)
  1497. * @returns {Array[State]} an array of states for the respective values.
  1498. */
  1499. Promise.prototype.allSettled = function () {
  1500. return this.then(function (promises) {
  1501. return all(array_map(promises, function (promise) {
  1502. promise = Q(promise);
  1503. function regardless() {
  1504. return promise.inspect();
  1505. }
  1506. return promise.then(regardless, regardless);
  1507. }));
  1508. });
  1509. };
  1510. /**
  1511. * Captures the failure of a promise, giving an oportunity to recover
  1512. * with a callback. If the given promise is fulfilled, the returned
  1513. * promise is fulfilled.
  1514. * @param {Any*} promise for something
  1515. * @param {Function} callback to fulfill the returned promise if the
  1516. * given promise is rejected
  1517. * @returns a promise for the return value of the callback
  1518. */
  1519. Q.fail = // XXX legacy
  1520. Q["catch"] = function (object, rejected) {
  1521. return Q(object).then(void 0, rejected);
  1522. };
  1523. Promise.prototype.fail = // XXX legacy
  1524. Promise.prototype["catch"] = function (rejected) {
  1525. return this.then(void 0, rejected);
  1526. };
  1527. /**
  1528. * Attaches a listener that can respond to progress notifications from a
  1529. * promise's originating deferred. This listener receives the exact arguments
  1530. * passed to ``deferred.notify``.
  1531. * @param {Any*} promise for something
  1532. * @param {Function} callback to receive any progress notifications
  1533. * @returns the given promise, unchanged
  1534. */
  1535. Q.progress = progress;
  1536. function progress(object, progressed) {
  1537. return Q(object).then(void 0, void 0, progressed);
  1538. }
  1539. Promise.prototype.progress = function (progressed) {
  1540. return this.then(void 0, void 0, progressed);
  1541. };
  1542. /**
  1543. * Provides an opportunity to observe the settling of a promise,
  1544. * regardless of whether the promise is fulfilled or rejected. Forwards
  1545. * the resolution to the returned promise when the callback is done.
  1546. * The callback can return a promise to defer completion.
  1547. * @param {Any*} promise
  1548. * @param {Function} callback to observe the resolution of the given
  1549. * promise, takes no arguments.
  1550. * @returns a promise for the resolution of the given promise when
  1551. * ``fin`` is done.
  1552. */
  1553. Q.fin = // XXX legacy
  1554. Q["finally"] = function (object, callback) {
  1555. return Q(object)["finally"](callback);
  1556. };
  1557. Promise.prototype.fin = // XXX legacy
  1558. Promise.prototype["finally"] = function (callback) {
  1559. callback = Q(callback);
  1560. return this.then(function (value) {
  1561. return callback.fcall().then(function () {
  1562. return value;
  1563. });
  1564. }, function (reason) {
  1565. // TODO attempt to recycle the rejection with "this".
  1566. return callback.fcall().then(function () {
  1567. throw reason;
  1568. });
  1569. });
  1570. };
  1571. /**
  1572. * Terminates a chain of promises, forcing rejections to be
  1573. * thrown as exceptions.
  1574. * @param {Any*} promise at the end of a chain of promises
  1575. * @returns nothing
  1576. */
  1577. Q.done = function (object, fulfilled, rejected, progress) {
  1578. return Q(object).done(fulfilled, rejected, progress);
  1579. };
  1580. Promise.prototype.done = function (fulfilled, rejected, progress) {
  1581. var onUnhandledError = function (error) {
  1582. // forward to a future turn so that ``when``
  1583. // does not catch it and turn it into a rejection.
  1584. Q.nextTick(function () {
  1585. makeStackTraceLong(error, promise);
  1586. if (Q.onerror) {
  1587. Q.onerror(error);
  1588. } else {
  1589. throw error;
  1590. }
  1591. });
  1592. };
  1593. // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
  1594. var promise = fulfilled || rejected || progress ?
  1595. this.then(fulfilled, rejected, progress) :
  1596. this;
  1597. if (typeof process === "object" && process && process.domain) {
  1598. onUnhandledError = process.domain.bind(onUnhandledError);
  1599. }
  1600. promise.then(void 0, onUnhandledError);
  1601. };
  1602. /**
  1603. * Causes a promise to be rejected if it does not get fulfilled before
  1604. * some milliseconds time out.
  1605. * @param {Any*} promise
  1606. * @param {Number} milliseconds timeout
  1607. * @param {Any*} custom error message or Error object (optional)
  1608. * @returns a promise for the resolution of the given promise if it is
  1609. * fulfilled before the timeout, otherwise rejected.
  1610. */
  1611. Q.timeout = function (object, ms, error) {
  1612. return Q(object).timeout(ms, error);
  1613. };
  1614. Promise.prototype.timeout = function (ms, error) {
  1615. var deferred = defer();
  1616. var timeoutId = setTimeout(function () {
  1617. if (!error || "string" === typeof error) {
  1618. error = new Error(error || "Timed out after " + ms + " ms");
  1619. error.code = "ETIMEDOUT";
  1620. }
  1621. deferred.reject(error);
  1622. }, ms);
  1623. this.then(function (value) {
  1624. clearTimeout(timeoutId);
  1625. deferred.resolve(value);
  1626. }, function (exception) {
  1627. clearTimeout(timeoutId);
  1628. deferred.reject(exception);
  1629. }, deferred.notify);
  1630. return deferred.promise;
  1631. };
  1632. /**
  1633. * Returns a promise for the given value (or promised value), some
  1634. * milliseconds after it resolved. Passes rejections immediately.
  1635. * @param {Any*} promise
  1636. * @param {Number} milliseconds
  1637. * @returns a promise for the resolution of the given promise after milliseconds
  1638. * time has elapsed since the resolution of the given promise.
  1639. * If the given promise rejects, that is passed immediately.
  1640. */
  1641. Q.delay = function (object, timeout) {
  1642. if (timeout === void 0) {
  1643. timeout = object;
  1644. object = void 0;
  1645. }
  1646. return Q(object).delay(timeout);
  1647. };
  1648. Promise.prototype.delay = function (timeout) {
  1649. return this.then(function (value) {
  1650. var deferred = defer();
  1651. setTimeout(function () {
  1652. deferred.resolve(value);
  1653. }, timeout);
  1654. return deferred.promise;
  1655. });
  1656. };
  1657. /**
  1658. * Passes a continuation to a Node function, which is called with the given
  1659. * arguments provided as an array, and returns a promise.
  1660. *
  1661. * Q.nfapply(FS.readFile, [__filename])
  1662. * .then(function (content) {
  1663. * })
  1664. *
  1665. */
  1666. Q.nfapply = function (callback, args) {
  1667. return Q(callback).nfapply(args);
  1668. };
  1669. Promise.prototype.nfapply = function (args) {
  1670. var deferred = defer();
  1671. var nodeArgs = array_slice(args);
  1672. nodeArgs.push(deferred.makeNodeResolver());
  1673. this.fapply(nodeArgs).fail(deferred.reject);
  1674. return deferred.promise;
  1675. };
  1676. /**
  1677. * Passes a continuation to a Node function, which is called with the given
  1678. * arguments provided individually, and returns a promise.
  1679. * @example
  1680. * Q.nfcall(FS.readFile, __filename)
  1681. * .then(function (content) {
  1682. * })
  1683. *
  1684. */
  1685. Q.nfcall = function (callback /*...args*/) {
  1686. var args = array_slice(arguments, 1);
  1687. return Q(callback).nfapply(args);
  1688. };
  1689. Promise.prototype.nfcall = function (/*...args*/) {
  1690. var nodeArgs = array_slice(arguments);
  1691. var deferred = defer();
  1692. nodeArgs.push(deferred.makeNodeResolver());
  1693. this.fapply(nodeArgs).fail(deferred.reject);
  1694. return deferred.promise;
  1695. };
  1696. /**
  1697. * Wraps a NodeJS continuation passing function and returns an equivalent
  1698. * version that returns a promise.
  1699. * @example
  1700. * Q.nfbind(FS.readFile, __filename)("utf-8")
  1701. * .then(console.log)
  1702. * .done()
  1703. */
  1704. Q.nfbind =
  1705. Q.denodeify = function (callback /*...args*/) {
  1706. var baseArgs = array_slice(arguments, 1);
  1707. return function () {
  1708. var nodeArgs = baseArgs.concat(array_slice(arguments));
  1709. var deferred = defer();
  1710. nodeArgs.push(deferred.makeNodeResolver());
  1711. Q(callback).fapply(nodeArgs).fail(deferred.reject);
  1712. return deferred.promise;
  1713. };
  1714. };
  1715. Promise.prototype.nfbind =
  1716. Promise.prototype.denodeify = function (/*...args*/) {
  1717. var args = array_slice(arguments);
  1718. args.unshift(this);
  1719. return Q.denodeify.apply(void 0, args);
  1720. };
  1721. Q.nbind = function (callback, thisp /*...args*/) {
  1722. var baseArgs = array_slice(arguments, 2);
  1723. return function () {
  1724. var nodeArgs = baseArgs.concat(array_slice(arguments));
  1725. var deferred = defer();
  1726. nodeArgs.push(deferred.makeNodeResolver());
  1727. function bound() {
  1728. return callback.apply(thisp, arguments);
  1729. }
  1730. Q(bound).fapply(nodeArgs).fail(deferred.reject);
  1731. return deferred.promise;
  1732. };
  1733. };
  1734. Promise.prototype.nbind = function (/*thisp, ...args*/) {
  1735. var args = array_slice(arguments, 0);
  1736. args.unshift(this);
  1737. return Q.nbind.apply(void 0, args);
  1738. };
  1739. /**
  1740. * Calls a method of a Node-style object that accepts a Node-style
  1741. * callback with a given array of arguments, plus a provided callback.
  1742. * @param object an object that has the named method
  1743. * @param {String} name name of the method of object
  1744. * @param {Array} args arguments to pass to the method; the callback
  1745. * will be provided by Q and appended to these arguments.
  1746. * @returns a promise for the value or error
  1747. */
  1748. Q.nmapply = // XXX As proposed by "Redsandro"
  1749. Q.npost = function (object, name, args) {
  1750. return Q(object).npost(name, args);
  1751. };
  1752. Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
  1753. Promise.prototype.npost = function (name, args) {
  1754. var nodeArgs = array_slice(args || []);
  1755. var deferred = defer();
  1756. nodeArgs.push(deferred.makeNodeResolver());
  1757. this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
  1758. return deferred.promise;
  1759. };
  1760. /**
  1761. * Calls a method of a Node-style object that accepts a Node-style
  1762. * callback, forwarding the given variadic arguments, plus a provided
  1763. * callback argument.
  1764. * @param object an object that has the named method
  1765. * @param {String} name name of the method of object
  1766. * @param ...args arguments to pass to the method; the callback will
  1767. * be provided by Q and appended to these arguments.
  1768. * @returns a promise for the value or error
  1769. */
  1770. Q.nsend = // XXX Based on Mark Miller's proposed "send"
  1771. Q.nmcall = // XXX Based on "Redsandro's" proposal
  1772. Q.ninvoke = function (object, name /*...args*/) {
  1773. var nodeArgs = array_slice(arguments, 2);
  1774. var deferred = defer();
  1775. nodeArgs.push(deferred.makeNodeResolver());
  1776. Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
  1777. return deferred.promise;
  1778. };
  1779. Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
  1780. Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
  1781. Promise.prototype.ninvoke = function (name /*...args*/) {
  1782. var nodeArgs = array_slice(arguments, 1);
  1783. var deferred = defer();
  1784. nodeArgs.push(deferred.makeNodeResolver());
  1785. this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
  1786. return deferred.promise;
  1787. };
  1788. /**
  1789. * If a function would like to support both Node continuation-passing-style and
  1790. * promise-returning-style, it can end its internal promise chain with
  1791. * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
  1792. * elects to use a nodeback, the result will be sent there. If they do not
  1793. * pass a nodeback, they will receive the result promise.
  1794. * @param object a result (or a promise for a result)
  1795. * @param {Function} nodeback a Node.js-style callback
  1796. * @returns either the promise or nothing
  1797. */
  1798. Q.nodeify = nodeify;
  1799. function nodeify(object, nodeback) {
  1800. return Q(object).nodeify(nodeback);
  1801. }
  1802. Promise.prototype.nodeify = function (nodeback) {
  1803. if (nodeback) {
  1804. this.then(function (value) {
  1805. Q.nextTick(function () {
  1806. nodeback(null, value);
  1807. });
  1808. }, function (error) {
  1809. Q.nextTick(function () {
  1810. nodeback(error);
  1811. });
  1812. });
  1813. } else {
  1814. return this;
  1815. }
  1816. };
  1817. Q.noConflict = function() {
  1818. throw new Error("Q.noConflict only works when Q is used as a global");
  1819. };
  1820. // All code before this point will be filtered from stack traces.
  1821. var qEndingLine = captureLine();
  1822. return Q;
  1823. });