q.js 57 KB

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