You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2076 lines
62 KiB

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