q.js 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525
  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, -W117*/
  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. // All code after this point will be filtered from stack traces reported
  58. // by Q.
  59. var qStartingLine = captureLine();
  60. var qFileName;
  61. // shims
  62. // used for fallback in "allResolved"
  63. var noop = function () {};
  64. // Use the fastest possible means to execute a task in a future turn
  65. // of the event loop.
  66. var nextTick;
  67. if (typeof setImmediate === "function") {
  68. // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
  69. if (typeof window !== "undefined") {
  70. nextTick = setImmediate.bind(window);
  71. } else {
  72. nextTick = setImmediate;
  73. }
  74. } else if (typeof process !== "undefined" && process.nextTick) {
  75. // Node.js before 0.9. Note that some fake-Node environments, like the
  76. // Mocha test runner, introduce a `process` global without a `nextTick`.
  77. nextTick = process.nextTick;
  78. } else {
  79. (function () {
  80. // linked list of tasks (single, with head node)
  81. var head = {task: void 0, next: null};
  82. var tail = head;
  83. var maxPendingTicks = 2;
  84. var pendingTicks = 0;
  85. var queuedTasks = 0;
  86. var usedTicks = 0;
  87. var requestTick = void 0;
  88. function onTick() {
  89. // In case of multiple tasks ensure at least one subsequent tick
  90. // to handle remaining tasks in case one throws.
  91. --pendingTicks;
  92. if (++usedTicks >= maxPendingTicks) {
  93. // Amortize latency after thrown exceptions.
  94. usedTicks = 0;
  95. maxPendingTicks *= 4; // fast grow!
  96. var expectedTicks = queuedTasks && Math.min(
  97. queuedTasks - 1,
  98. maxPendingTicks
  99. );
  100. while (pendingTicks < expectedTicks) {
  101. ++pendingTicks;
  102. requestTick();
  103. }
  104. }
  105. while (queuedTasks) {
  106. --queuedTasks; // decrement here to ensure it's never negative
  107. head = head.next;
  108. var task = head.task;
  109. head.task = void 0;
  110. task();
  111. }
  112. usedTicks = 0;
  113. }
  114. nextTick = function (task) {
  115. tail = tail.next = {task: task, next: null};
  116. if (
  117. pendingTicks < ++queuedTasks &&
  118. pendingTicks < maxPendingTicks
  119. ) {
  120. ++pendingTicks;
  121. requestTick();
  122. }
  123. };
  124. if (typeof MessageChannel !== "undefined") {
  125. // modern browsers
  126. // http://www.nonblocking.io/2011/06/windownexttick.html
  127. var channel = new MessageChannel();
  128. channel.port1.onmessage = onTick;
  129. requestTick = function () {
  130. channel.port2.postMessage(0);
  131. };
  132. } else {
  133. // old browsers
  134. requestTick = function () {
  135. setTimeout(onTick, 0);
  136. };
  137. }
  138. })();
  139. }
  140. // Attempt to make generics safe in the face of downstream
  141. // modifications.
  142. // There is no situation where this is necessary.
  143. // If you need a security guarantee, these primordials need to be
  144. // deeply frozen anyway, and if you don’t need a security guarantee,
  145. // this is just plain paranoid.
  146. // However, this does have the nice side-effect of reducing the size
  147. // of the code by reducing x.call() to merely x(), eliminating many
  148. // hard-to-minify characters.
  149. // See Mark Miller’s explanation of what this does.
  150. // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
  151. function uncurryThis(f) {
  152. var call = Function.call;
  153. return function () {
  154. return call.apply(f, arguments);
  155. };
  156. }
  157. // This is equivalent, but slower:
  158. // uncurryThis = Function_bind.bind(Function_bind.call);
  159. // http://jsperf.com/uncurrythis
  160. var array_slice = uncurryThis(Array.prototype.slice);
  161. var array_reduce = uncurryThis(
  162. Array.prototype.reduce || function (callback, basis) {
  163. var index = 0,
  164. length = this.length;
  165. // concerning the initial value, if one is not provided
  166. if (arguments.length === 1) {
  167. // seek to the first value in the array, accounting
  168. // for the possibility that is is a sparse array
  169. do {
  170. if (index in this) {
  171. basis = this[index++];
  172. break;
  173. }
  174. if (++index >= length) {
  175. throw new TypeError();
  176. }
  177. } while (1);
  178. }
  179. // reduce
  180. for (; index < length; index++) {
  181. // account for the possibility that the array is sparse
  182. if (index in this) {
  183. basis = callback(basis, this[index], index);
  184. }
  185. }
  186. return basis;
  187. }
  188. );
  189. var array_indexOf = uncurryThis(
  190. Array.prototype.indexOf || function (value) {
  191. // not a very good shim, but good enough for our one use of it
  192. for (var i = 0; i < this.length; i++) {
  193. if (this[i] === value) {
  194. return i;
  195. }
  196. }
  197. return -1;
  198. }
  199. );
  200. var array_map = uncurryThis(
  201. Array.prototype.map || function (callback, thisp) {
  202. var self = this;
  203. var collect = [];
  204. array_reduce(self, function (undefined, value, index) {
  205. collect.push(callback.call(thisp, value, index, self));
  206. }, void 0);
  207. return collect;
  208. }
  209. );
  210. var object_create = Object.create || function (prototype) {
  211. function Type() { }
  212. Type.prototype = prototype;
  213. return new Type();
  214. };
  215. var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
  216. var object_keys = Object.keys || function (object) {
  217. var keys = [];
  218. for (var key in object) {
  219. if (object_hasOwnProperty(object, key)) {
  220. keys.push(key);
  221. }
  222. }
  223. return keys;
  224. };
  225. var object_toString = uncurryThis(Object.prototype.toString);
  226. // generator related shims
  227. function isStopIteration(exception) {
  228. return (
  229. object_toString(exception) === "[object StopIteration]" ||
  230. exception instanceof QReturnValue
  231. );
  232. }
  233. var QReturnValue;
  234. if (typeof ReturnValue !== "undefined") {
  235. QReturnValue = ReturnValue;
  236. } else {
  237. QReturnValue = function (value) {
  238. this.value = value;
  239. };
  240. }
  241. // long stack traces
  242. Q.longStackJumpLimit = 1;
  243. var STACK_JUMP_SEPARATOR = "From previous event:";
  244. function makeStackTraceLong(error, promise) {
  245. // If possible (that is, if in V8), transform the error stack
  246. // trace by removing Node and Q cruft, then concatenating with
  247. // the stack trace of the promise we are ``done``ing. See #57.
  248. if (promise.stack &&
  249. typeof error === "object" &&
  250. error !== null &&
  251. error.stack &&
  252. error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
  253. ) {
  254. error.stack = filterStackString(error.stack) +
  255. "\n" + STACK_JUMP_SEPARATOR + "\n" +
  256. filterStackString(promise.stack);
  257. }
  258. }
  259. function filterStackString(stackString) {
  260. var lines = stackString.split("\n");
  261. var desiredLines = [];
  262. for (var i = 0; i < lines.length; ++i) {
  263. var line = lines[i];
  264. if (!isInternalFrame(line) && !isNodeFrame(line)) {
  265. desiredLines.push(line);
  266. }
  267. }
  268. return desiredLines.join("\n");
  269. }
  270. function isNodeFrame(stackLine) {
  271. return stackLine.indexOf("(module.js:") !== -1 ||
  272. stackLine.indexOf("(node.js:") !== -1;
  273. }
  274. function isInternalFrame(stackLine) {
  275. var pieces = /at .+ \((.*):(\d+):\d+\)/.exec(stackLine);
  276. if (!pieces) {
  277. return false;
  278. }
  279. var fileName = pieces[1];
  280. var lineNumber = pieces[2];
  281. return fileName === qFileName &&
  282. lineNumber >= qStartingLine &&
  283. lineNumber <= qEndingLine;
  284. }
  285. // discover own file name and line number range for filtering stack
  286. // traces
  287. function captureLine() {
  288. if (Error.captureStackTrace) {
  289. var fileName, lineNumber;
  290. var oldPrepareStackTrace = Error.prepareStackTrace;
  291. Error.prepareStackTrace = function (error, frames) {
  292. fileName = frames[1].getFileName();
  293. lineNumber = frames[1].getLineNumber();
  294. };
  295. // teases call of temporary prepareStackTrace
  296. // JSHint and Closure Compiler generate known warnings here
  297. /*jshint expr: true */
  298. new Error().stack;
  299. Error.prepareStackTrace = oldPrepareStackTrace;
  300. qFileName = fileName;
  301. return lineNumber;
  302. }
  303. }
  304. // end of shims
  305. // beginning of real work
  306. /**
  307. * Creates fulfilled promises from non-promises,
  308. * Passes Q promises through,
  309. * Coerces thenables to Q promises.
  310. */
  311. function Q(value) {
  312. return resolve(value);
  313. }
  314. /**
  315. * Performs a task in a future turn of the event loop.
  316. * @param {Function} task
  317. */
  318. Q.nextTick = nextTick;
  319. /**
  320. * Constructs a {promise, resolve} object.
  321. *
  322. * The resolver is a callback to invoke with a more resolved value for the
  323. * promise. To fulfill the promise, invoke the resolver with any value that is
  324. * not a function. To reject the promise, invoke the resolver with a rejection
  325. * object. To put the promise in the same state as another promise, invoke the
  326. * resolver with that other promise.
  327. */
  328. Q.defer = defer;
  329. function defer() {
  330. // if "pending" is an "Array", that indicates that the promise has not yet
  331. // been resolved. If it is "undefined", it has been resolved. Each
  332. // element of the pending array is itself an array of complete arguments to
  333. // forward to the resolved promise. We coerce the resolution value to a
  334. // promise using the ref promise because it handles both fully
  335. // resolved values and other promises gracefully.
  336. var pending = [], progressListeners = [], resolvedPromise;
  337. var deferred = object_create(defer.prototype);
  338. var promise = object_create(makePromise.prototype);
  339. promise.promiseDispatch = function (resolve, op, operands) {
  340. var args = array_slice(arguments);
  341. if (pending) {
  342. pending.push(args);
  343. if (op === "when" && operands[1]) { // progress operand
  344. progressListeners.push(operands[1]);
  345. }
  346. } else {
  347. nextTick(function () {
  348. resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
  349. });
  350. }
  351. };
  352. promise.valueOf = function () {
  353. if (pending) {
  354. return promise;
  355. }
  356. var nearer = valueOf(resolvedPromise);
  357. if (isPromise(nearer)) {
  358. resolvedPromise = nearer; // shorten chain
  359. }
  360. return nearer;
  361. };
  362. if (Error.captureStackTrace && Q.longStackJumpLimit > 0) {
  363. Error.captureStackTrace(promise, defer);
  364. // Reify the stack into a string by using the accessor; this prevents
  365. // memory leaks as per GH-111. At the same time, cut off the first line;
  366. // it's always just "[object Promise]\n", as per the `toString`.
  367. promise.stack = promise.stack.substring(
  368. promise.stack.indexOf("\n") + 1
  369. );
  370. }
  371. // NOTE: we do the checks for `resolvedPromise` in each method, instead of
  372. // consolidating them into `become`, since otherwise we'd create new
  373. // promises with the lines `become(whatever(value))`. See e.g. GH-252.
  374. function become(promise) {
  375. resolvedPromise = promise;
  376. array_reduce(pending, function (undefined, pending) {
  377. nextTick(function () {
  378. promise.promiseDispatch.apply(promise, pending);
  379. });
  380. }, void 0);
  381. pending = void 0;
  382. progressListeners = void 0;
  383. }
  384. deferred.promise = promise;
  385. deferred.resolve = function (value) {
  386. if (resolvedPromise) {
  387. return;
  388. }
  389. become(resolve(value));
  390. };
  391. deferred.fulfill = function (value) {
  392. if (resolvedPromise) {
  393. return;
  394. }
  395. become(fulfill(value));
  396. };
  397. deferred.reject = function (reason) {
  398. if (resolvedPromise) {
  399. return;
  400. }
  401. become(reject(reason));
  402. };
  403. deferred.notify = function (progress) {
  404. if (resolvedPromise) {
  405. return;
  406. }
  407. array_reduce(progressListeners, function (undefined, progressListener) {
  408. nextTick(function () {
  409. progressListener(progress);
  410. });
  411. }, void 0);
  412. };
  413. return deferred;
  414. }
  415. /**
  416. * Creates a Node-style callback that will resolve or reject the deferred
  417. * promise.
  418. * @returns a nodeback
  419. */
  420. defer.prototype.makeNodeResolver = function () {
  421. var self = this;
  422. return function (error, value) {
  423. if (error) {
  424. self.reject(error);
  425. } else if (arguments.length > 2) {
  426. self.resolve(array_slice(arguments, 1));
  427. } else {
  428. self.resolve(value);
  429. }
  430. };
  431. };
  432. /**
  433. * @param resolver {Function} a function that returns nothing and accepts
  434. * the resolve, reject, and notify functions for a deferred.
  435. * @returns a promise that may be resolved with the given resolve and reject
  436. * functions, or rejected by a thrown exception in resolver
  437. */
  438. Q.promise = promise;
  439. function promise(resolver) {
  440. if (typeof resolver !== "function") {
  441. throw new TypeError("resolver must be a function.");
  442. }
  443. var deferred = defer();
  444. fcall(
  445. resolver,
  446. deferred.resolve,
  447. deferred.reject,
  448. deferred.notify
  449. ).fail(deferred.reject);
  450. return deferred.promise;
  451. }
  452. /**
  453. * Constructs a Promise with a promise descriptor object and optional fallback
  454. * function. The descriptor contains methods like when(rejected), get(name),
  455. * set(name, value), post(name, args), and delete(name), which all
  456. * return either a value, a promise for a value, or a rejection. The fallback
  457. * accepts the operation name, a resolver, and any further arguments that would
  458. * have been forwarded to the appropriate method above had a method been
  459. * provided with the proper name. The API makes no guarantees about the nature
  460. * of the returned object, apart from that it is usable whereever promises are
  461. * bought and sold.
  462. */
  463. Q.makePromise = makePromise;
  464. function makePromise(descriptor, fallback, valueOf, exception, isException) {
  465. if (fallback === void 0) {
  466. fallback = function (op) {
  467. return reject(new Error(
  468. "Promise does not support operation: " + op
  469. ));
  470. };
  471. }
  472. var promise = object_create(makePromise.prototype);
  473. promise.promiseDispatch = function (resolve, op, args) {
  474. var result;
  475. try {
  476. if (descriptor[op]) {
  477. result = descriptor[op].apply(promise, args);
  478. } else {
  479. result = fallback.call(promise, op, args);
  480. }
  481. } catch (exception) {
  482. result = reject(exception);
  483. }
  484. if (resolve) {
  485. resolve(result);
  486. }
  487. };
  488. if (valueOf) {
  489. promise.valueOf = valueOf;
  490. }
  491. if (isException) {
  492. promise.exception = exception;
  493. }
  494. return promise;
  495. }
  496. // provide thenables, CommonJS/Promises/A
  497. makePromise.prototype.then = function (fulfilled, rejected, progressed) {
  498. return when(this, fulfilled, rejected, progressed);
  499. };
  500. makePromise.prototype.thenResolve = function (value) {
  501. return when(this, function () { return value; });
  502. };
  503. makePromise.prototype.thenReject = function (reason) {
  504. return when(this, function () { throw reason; });
  505. };
  506. // Chainable methods
  507. array_reduce(
  508. [
  509. "isFulfilled", "isRejected", "isPending",
  510. "dispatch",
  511. "when", "spread",
  512. "get", "set", "del", "delete",
  513. "post", "send", "invoke",
  514. "keys",
  515. "fapply", "fcall", "fbind",
  516. "all", "allResolved",
  517. "timeout", "delay",
  518. "catch", "finally", "fail", "fin", "progress", "done",
  519. "nfcall", "nfapply", "nfbind", "denodeify", "nbind",
  520. "npost", "nsend", "ninvoke",
  521. "nodeify"
  522. ],
  523. function (undefined, name) {
  524. makePromise.prototype[name] = function () {
  525. return Q[name].apply(
  526. Q,
  527. [this].concat(array_slice(arguments))
  528. );
  529. };
  530. },
  531. void 0
  532. );
  533. makePromise.prototype.toSource = function () {
  534. return this.toString();
  535. };
  536. makePromise.prototype.toString = function () {
  537. return "[object Promise]";
  538. };
  539. /**
  540. * If an object is not a promise, it is as "near" as possible.
  541. * If a promise is rejected, it is as "near" as possible too.
  542. * If it’s a fulfilled promise, the fulfillment value is nearer.
  543. * If it’s a deferred promise and the deferred has been resolved, the
  544. * resolution is "nearer".
  545. * @param object
  546. * @returns most resolved (nearest) form of the object
  547. */
  548. Q.nearer = valueOf;
  549. function valueOf(value) {
  550. if (isPromise(value)) {
  551. return value.valueOf();
  552. }
  553. return value;
  554. }
  555. /**
  556. * @returns whether the given object is a promise.
  557. * Otherwise it is a fulfilled value.
  558. */
  559. Q.isPromise = isPromise;
  560. function isPromise(object) {
  561. return object && typeof object.promiseDispatch === "function";
  562. }
  563. Q.isPromiseAlike = isPromiseAlike;
  564. function isPromiseAlike(object) {
  565. return object && typeof object.then === "function";
  566. }
  567. /**
  568. * @returns whether the given object is a pending promise, meaning not
  569. * fulfilled or rejected.
  570. */
  571. Q.isPending = isPending;
  572. function isPending(object) {
  573. return !isFulfilled(object) && !isRejected(object);
  574. }
  575. /**
  576. * @returns whether the given object is a value or fulfilled
  577. * promise.
  578. */
  579. Q.isFulfilled = isFulfilled;
  580. function isFulfilled(object) {
  581. return !isPromiseAlike(valueOf(object));
  582. }
  583. /**
  584. * @returns whether the given object is a rejected promise.
  585. */
  586. Q.isRejected = isRejected;
  587. function isRejected(object) {
  588. object = valueOf(object);
  589. return isPromise(object) && "exception" in object;
  590. }
  591. // This promise library consumes exceptions thrown in handlers so they can be
  592. // handled by a subsequent promise. The exceptions get added to this array when
  593. // they are created, and removed when they are handled. Note that in ES6 or
  594. // shimmed environments, this would naturally be a `Set`.
  595. var unhandledReasons = Q.unhandledReasons = [];
  596. var unhandledRejections = [];
  597. var unhandledReasonsDisplayed = false;
  598. function displayUnhandledReasons() {
  599. if (
  600. !unhandledReasonsDisplayed &&
  601. typeof window !== "undefined" &&
  602. !window.Touch &&
  603. window.console
  604. ) {
  605. console.warn("[Q] Unhandled rejection reasons (should be empty):",
  606. unhandledReasons);
  607. }
  608. unhandledReasonsDisplayed = true;
  609. }
  610. // Show unhandled rejection reasons if Node exits without handling an
  611. // outstanding rejection. (Note that Browserify presently produces a process
  612. // global without the `EventEmitter` `on` method.)
  613. if (typeof process !== "undefined" && process.on) {
  614. process.on("exit", function () {
  615. for (var i = 0; i < unhandledReasons.length; i++) {
  616. var reason = unhandledReasons[i];
  617. if (reason && typeof reason.stack !== "undefined") {
  618. console.warn("Unhandled rejection reason:", reason.stack);
  619. } else {
  620. console.warn("Unhandled rejection reason (no stack):", reason);
  621. }
  622. }
  623. });
  624. }
  625. /**
  626. * Constructs a rejected promise.
  627. * @param reason value describing the failure
  628. */
  629. Q.reject = reject;
  630. function reject(reason) {
  631. var rejection = makePromise({
  632. "when": function (rejected) {
  633. // note that the error has been handled
  634. if (rejected) {
  635. var at = array_indexOf(unhandledRejections, this);
  636. if (at !== -1) {
  637. unhandledRejections.splice(at, 1);
  638. unhandledReasons.splice(at, 1);
  639. }
  640. }
  641. return rejected ? rejected(reason) : this;
  642. }
  643. }, function fallback() {
  644. return reject(reason);
  645. }, function valueOf() {
  646. return this;
  647. }, reason, true);
  648. // Note that the reason has not been handled.
  649. displayUnhandledReasons();
  650. unhandledRejections.push(rejection);
  651. unhandledReasons.push(reason);
  652. return rejection;
  653. }
  654. /**
  655. * Constructs a fulfilled promise for an immediate reference.
  656. * @param value immediate reference
  657. */
  658. Q.fulfill = fulfill;
  659. function fulfill(object) {
  660. return makePromise({
  661. "when": function () {
  662. return object;
  663. },
  664. "get": function (name) {
  665. return object[name];
  666. },
  667. "set": function (name, value) {
  668. object[name] = value;
  669. },
  670. "delete": function (name) {
  671. delete object[name];
  672. },
  673. "post": function (name, args) {
  674. // Mark Miller proposes that post with no name should apply a
  675. // promised function.
  676. if (name === null || name === void 0) {
  677. return object.apply(void 0, args);
  678. } else {
  679. return object[name].apply(object, args);
  680. }
  681. },
  682. "apply": function (thisP, args) {
  683. return object.apply(thisP, args);
  684. },
  685. "keys": function () {
  686. return object_keys(object);
  687. }
  688. }, void 0, function valueOf() {
  689. return object;
  690. });
  691. }
  692. /**
  693. * Constructs a promise for an immediate reference, passes promises through, or
  694. * coerces promises from different systems.
  695. * @param value immediate reference or promise
  696. */
  697. Q.resolve = resolve;
  698. function resolve(value) {
  699. // If the object is already a Promise, return it directly. This enables
  700. // the resolve function to both be used to created references from objects,
  701. // but to tolerably coerce non-promises to promises.
  702. if (isPromise(value)) {
  703. return value;
  704. }
  705. // In order to break infinite recursion or loops between `then` and
  706. // `resolve`, it is necessary to attempt to extract fulfilled values
  707. // out of foreign promise implementations before attempting to wrap
  708. // them as unresolved promises. It is my hope that other
  709. // implementations will implement `valueOf` to synchronously extract
  710. // the fulfillment value from their fulfilled promises. If the
  711. // other promise library does not implement `valueOf`, the
  712. // implementations on primordial prototypes are harmless.
  713. value = valueOf(value);
  714. // assimilate thenables, CommonJS/Promises/A+
  715. if (isPromiseAlike(value)) {
  716. return coerce(value);
  717. } else {
  718. return fulfill(value);
  719. }
  720. }
  721. /**
  722. * Converts thenables to Q promises.
  723. * @param promise thenable promise
  724. * @returns a Q promise
  725. */
  726. function coerce(promise) {
  727. var deferred = defer();
  728. nextTick(function () {
  729. try {
  730. promise.then(deferred.resolve, deferred.reject, deferred.notify);
  731. } catch (exception) {
  732. deferred.reject(exception);
  733. }
  734. });
  735. return deferred.promise;
  736. }
  737. /**
  738. * Annotates an object such that it will never be
  739. * transferred away from this process over any promise
  740. * communication channel.
  741. * @param object
  742. * @returns promise a wrapping of that object that
  743. * additionally responds to the "isDef" message
  744. * without a rejection.
  745. */
  746. Q.master = master;
  747. function master(object) {
  748. return makePromise({
  749. "isDef": function () {}
  750. }, function fallback(op, args) {
  751. return dispatch(object, op, args);
  752. }, function () {
  753. return valueOf(object);
  754. });
  755. }
  756. /**
  757. * Registers an observer on a promise.
  758. *
  759. * Guarantees:
  760. *
  761. * 1. that fulfilled and rejected will be called only once.
  762. * 2. that either the fulfilled callback or the rejected callback will be
  763. * called, but not both.
  764. * 3. that fulfilled and rejected will not be called in this turn.
  765. *
  766. * @param value promise or immediate reference to observe
  767. * @param fulfilled function to be called with the fulfilled value
  768. * @param rejected function to be called with the rejection exception
  769. * @param progressed function to be called on any progress notifications
  770. * @return promise for the return value from the invoked callback
  771. */
  772. Q.when = when;
  773. function when(value, fulfilled, rejected, progressed) {
  774. var deferred = defer();
  775. var done = false; // ensure the untrusted promise makes at most a
  776. // single call to one of the callbacks
  777. function _fulfilled(value) {
  778. try {
  779. return typeof fulfilled === "function" ? fulfilled(value) : value;
  780. } catch (exception) {
  781. return reject(exception);
  782. }
  783. }
  784. function _rejected(exception) {
  785. if (typeof rejected === "function") {
  786. makeStackTraceLong(exception, resolvedValue);
  787. try {
  788. return rejected(exception);
  789. } catch (newException) {
  790. return reject(newException);
  791. }
  792. }
  793. return reject(exception);
  794. }
  795. function _progressed(value) {
  796. return typeof progressed === "function" ? progressed(value) : value;
  797. }
  798. var resolvedValue = resolve(value);
  799. nextTick(function () {
  800. resolvedValue.promiseDispatch(function (value) {
  801. if (done) {
  802. return;
  803. }
  804. done = true;
  805. deferred.resolve(_fulfilled(value));
  806. }, "when", [function (exception) {
  807. if (done) {
  808. return;
  809. }
  810. done = true;
  811. deferred.resolve(_rejected(exception));
  812. }]);
  813. });
  814. // Progress propagator need to be attached in the current tick.
  815. resolvedValue.promiseDispatch(void 0, "when", [void 0, function (value) {
  816. var newValue;
  817. var threw = false;
  818. try {
  819. newValue = _progressed(value);
  820. } catch (e) {
  821. threw = true;
  822. if (Q.onerror) {
  823. Q.onerror(e);
  824. } else {
  825. throw e;
  826. }
  827. }
  828. if (!threw) {
  829. deferred.notify(newValue);
  830. }
  831. }]);
  832. return deferred.promise;
  833. }
  834. /**
  835. * Spreads the values of a promised array of arguments into the
  836. * fulfillment callback.
  837. * @param fulfilled callback that receives variadic arguments from the
  838. * promised array
  839. * @param rejected callback that receives the exception if the promise
  840. * is rejected.
  841. * @returns a promise for the return value or thrown exception of
  842. * either callback.
  843. */
  844. Q.spread = spread;
  845. function spread(promise, fulfilled, rejected) {
  846. return when(promise, function (valuesOrPromises) {
  847. return all(valuesOrPromises).then(function (values) {
  848. return fulfilled.apply(void 0, values);
  849. }, rejected);
  850. }, rejected);
  851. }
  852. /**
  853. * The async function is a decorator for generator functions, turning
  854. * them into asynchronous generators. This presently only works in
  855. * Firefox/Spidermonkey, however, this code does not cause syntax
  856. * errors in older engines. This code should continue to work and
  857. * will in fact improve over time as the language improves.
  858. *
  859. * Decorates a generator function such that:
  860. * - it may yield promises
  861. * - execution will continue when that promise is fulfilled
  862. * - the value of the yield expression will be the fulfilled value
  863. * - it returns a promise for the return value (when the generator
  864. * stops iterating)
  865. * - the decorated function returns a promise for the return value
  866. * of the generator or the first rejected promise among those
  867. * yielded.
  868. * - if an error is thrown in the generator, it propagates through
  869. * every following yield until it is caught, or until it escapes
  870. * the generator function altogether, and is translated into a
  871. * rejection for the promise returned by the decorated generator.
  872. * - in present implementations of generators, when a generator
  873. * function is complete, it throws ``StopIteration``, ``return`` is
  874. * a syntax error in the presence of ``yield``, so there is no
  875. * observable return value. There is a proposal[1] to add support
  876. * for ``return``, which would permit the value to be carried by a
  877. * ``StopIteration`` instance, in which case it would fulfill the
  878. * promise returned by the asynchronous generator. This can be
  879. * emulated today by throwing StopIteration explicitly with a value
  880. * property.
  881. *
  882. * [1]: http://wiki.ecmascript.org/doku.php?id=strawman:async_functions#reference_implementation
  883. *
  884. */
  885. Q.async = async;
  886. function async(makeGenerator) {
  887. return function () {
  888. // when verb is "send", arg is a value
  889. // when verb is "throw", arg is an exception
  890. function continuer(verb, arg) {
  891. var result;
  892. try {
  893. result = generator[verb](arg);
  894. } catch (exception) {
  895. if (isStopIteration(exception)) {
  896. return exception.value;
  897. } else {
  898. return reject(exception);
  899. }
  900. }
  901. return when(result, callback, errback);
  902. }
  903. var generator = makeGenerator.apply(this, arguments);
  904. var callback = continuer.bind(continuer, "send");
  905. var errback = continuer.bind(continuer, "throw");
  906. return callback();
  907. };
  908. }
  909. /**
  910. * Throws a ReturnValue exception to stop an asynchronous generator.
  911. * Only useful presently in Firefox/SpiderMonkey since generators are
  912. * implemented.
  913. * @param value the return value for the surrounding generator
  914. * @throws ReturnValue exception with the value.
  915. * @example
  916. * Q.async(function () {
  917. * var foo = yield getFooPromise();
  918. * var bar = yield getBarPromise();
  919. * Q.return(foo + bar);
  920. * })
  921. */
  922. Q["return"] = _return;
  923. function _return(value) {
  924. throw new QReturnValue(value);
  925. }
  926. /**
  927. * The promised function decorator ensures that any promise arguments
  928. * are resolved and passed as values (`this` is also resolved and passed
  929. * as a value). It will also ensure that the result of a function is
  930. * always a promise.
  931. *
  932. * @example
  933. * var add = Q.promised(function (a, b) {
  934. * return a + b;
  935. * });
  936. * add(Q.resolve(a), Q.resolve(B));
  937. *
  938. * @param {function} callback The function to decorate
  939. * @returns {function} a function that has been decorated.
  940. */
  941. Q.promised = promised;
  942. function promised(callback) {
  943. return function () {
  944. return spread([this, all(arguments)], function (self, args) {
  945. return callback.apply(self, args);
  946. });
  947. };
  948. }
  949. /**
  950. * sends a message to a value in a future turn
  951. * @param object* the recipient
  952. * @param op the name of the message operation, e.g., "when",
  953. * @param args further arguments to be forwarded to the operation
  954. * @returns result {Promise} a promise for the result of the operation
  955. */
  956. Q.dispatch = dispatch;
  957. function dispatch(object, op, args) {
  958. var deferred = defer();
  959. nextTick(function () {
  960. resolve(object).promiseDispatch(deferred.resolve, op, args);
  961. });
  962. return deferred.promise;
  963. }
  964. /**
  965. * Constructs a promise method that can be used to safely observe resolution of
  966. * a promise for an arbitrarily named method like "propfind" in a future turn.
  967. *
  968. * "dispatcher" constructs methods like "get(promise, name)" and "set(promise)".
  969. */
  970. Q.dispatcher = dispatcher;
  971. function dispatcher(op) {
  972. return function (object) {
  973. var args = array_slice(arguments, 1);
  974. return dispatch(object, op, args);
  975. };
  976. }
  977. /**
  978. * Gets the value of a property in a future turn.
  979. * @param object promise or immediate reference for target object
  980. * @param name name of property to get
  981. * @return promise for the property value
  982. */
  983. Q.get = dispatcher("get");
  984. /**
  985. * Sets the value of a property in a future turn.
  986. * @param object promise or immediate reference for object object
  987. * @param name name of property to set
  988. * @param value new value of property
  989. * @return promise for the return value
  990. */
  991. Q.set = dispatcher("set");
  992. /**
  993. * Deletes a property in a future turn.
  994. * @param object promise or immediate reference for target object
  995. * @param name name of property to delete
  996. * @return promise for the return value
  997. */
  998. Q["delete"] = // XXX experimental
  999. Q.del = dispatcher("delete");
  1000. /**
  1001. * Invokes a method in a future turn.
  1002. * @param object promise or immediate reference for target object
  1003. * @param name name of method to invoke
  1004. * @param value a value to post, typically an array of
  1005. * invocation arguments for promises that
  1006. * are ultimately backed with `resolve` values,
  1007. * as opposed to those backed with URLs
  1008. * wherein the posted value can be any
  1009. * JSON serializable object.
  1010. * @return promise for the return value
  1011. */
  1012. // bound locally because it is used by other methods
  1013. var post = Q.post = dispatcher("post");
  1014. /**
  1015. * Invokes a method in a future turn.
  1016. * @param object promise or immediate reference for target object
  1017. * @param name name of method to invoke
  1018. * @param ...args array of invocation arguments
  1019. * @return promise for the return value
  1020. */
  1021. Q.send = send;
  1022. Q.invoke = send; // synonyms
  1023. function send(value, name) {
  1024. var args = array_slice(arguments, 2);
  1025. return post(value, name, args);
  1026. }
  1027. /**
  1028. * Applies the promised function in a future turn.
  1029. * @param object promise or immediate reference for target function
  1030. * @param args array of application arguments
  1031. */
  1032. Q.fapply = fapply;
  1033. function fapply(value, args) {
  1034. return dispatch(value, "apply", [void 0, args]);
  1035. }
  1036. /**
  1037. * Calls the promised function in a future turn.
  1038. * @param object promise or immediate reference for target function
  1039. * @param ...args array of application arguments
  1040. */
  1041. Q["try"] = fcall; // XXX experimental
  1042. Q.fcall = fcall;
  1043. function fcall(value) {
  1044. var args = array_slice(arguments, 1);
  1045. return fapply(value, args);
  1046. }
  1047. /**
  1048. * Binds the promised function, transforming return values into a fulfilled
  1049. * promise and thrown errors into a rejected one.
  1050. * @param object promise or immediate reference for target function
  1051. * @param ...args array of application arguments
  1052. */
  1053. Q.fbind = fbind;
  1054. function fbind(value) {
  1055. var args = array_slice(arguments, 1);
  1056. return function fbound() {
  1057. var allArgs = args.concat(array_slice(arguments));
  1058. return dispatch(value, "apply", [this, allArgs]);
  1059. };
  1060. }
  1061. /**
  1062. * Requests the names of the owned properties of a promised
  1063. * object in a future turn.
  1064. * @param object promise or immediate reference for target object
  1065. * @return promise for the keys of the eventually resolved object
  1066. */
  1067. Q.keys = dispatcher("keys");
  1068. /**
  1069. * Turns an array of promises into a promise for an array. If any of
  1070. * the promises gets rejected, the whole array is rejected immediately.
  1071. * @param {Array*} an array (or promise for an array) of values (or
  1072. * promises for values)
  1073. * @returns a promise for an array of the corresponding values
  1074. */
  1075. // By Mark Miller
  1076. // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
  1077. Q.all = all;
  1078. function all(promises) {
  1079. return when(promises, function (promises) {
  1080. var countDown = 0;
  1081. var deferred = defer();
  1082. array_reduce(promises, function (undefined, promise, index) {
  1083. if (isFulfilled(promise)) {
  1084. promises[index] = valueOf(promise);
  1085. } else {
  1086. ++countDown;
  1087. when(promise, function (value) {
  1088. promises[index] = value;
  1089. if (--countDown === 0) {
  1090. deferred.resolve(promises);
  1091. }
  1092. }, deferred.reject);
  1093. }
  1094. }, void 0);
  1095. if (countDown === 0) {
  1096. deferred.resolve(promises);
  1097. }
  1098. return deferred.promise;
  1099. });
  1100. }
  1101. /**
  1102. * Waits for all promises to be resolved, either fulfilled or
  1103. * rejected. This is distinct from `all` since that would stop
  1104. * waiting at the first rejection. The promise returned by
  1105. * `allResolved` will never be rejected.
  1106. * @param promises a promise for an array (or an array) of promises
  1107. * (or values)
  1108. * @return a promise for an array of promises
  1109. */
  1110. Q.allResolved = allResolved;
  1111. function allResolved(promises) {
  1112. return when(promises, function (promises) {
  1113. promises = array_map(promises, resolve);
  1114. return when(all(array_map(promises, function (promise) {
  1115. return when(promise, noop, noop);
  1116. })), function () {
  1117. return promises;
  1118. });
  1119. });
  1120. }
  1121. /**
  1122. * Captures the failure of a promise, giving an oportunity to recover
  1123. * with a callback. If the given promise is fulfilled, the returned
  1124. * promise is fulfilled.
  1125. * @param {Any*} promise for something
  1126. * @param {Function} callback to fulfill the returned promise if the
  1127. * given promise is rejected
  1128. * @returns a promise for the return value of the callback
  1129. */
  1130. Q["catch"] = // XXX experimental
  1131. Q.fail = fail;
  1132. function fail(promise, rejected) {
  1133. return when(promise, void 0, rejected);
  1134. }
  1135. /**
  1136. * Attaches a listener that can respond to progress notifications from a
  1137. * promise's originating deferred. This listener receives the exact arguments
  1138. * passed to ``deferred.notify``.
  1139. * @param {Any*} promise for something
  1140. * @param {Function} callback to receive any progress notifications
  1141. * @returns the given promise, unchanged
  1142. */
  1143. Q.progress = progress;
  1144. function progress(promise, progressed) {
  1145. return when(promise, void 0, void 0, progressed);
  1146. }
  1147. /**
  1148. * Provides an opportunity to observe the rejection of a promise,
  1149. * regardless of whether the promise is fulfilled or rejected. Forwards
  1150. * the resolution to the returned promise when the callback is done.
  1151. * The callback can return a promise to defer completion.
  1152. * @param {Any*} promise
  1153. * @param {Function} callback to observe the resolution of the given
  1154. * promise, takes no arguments.
  1155. * @returns a promise for the resolution of the given promise when
  1156. * ``fin`` is done.
  1157. */
  1158. Q["finally"] = // XXX experimental
  1159. Q.fin = fin;
  1160. function fin(promise, callback) {
  1161. return when(promise, function (value) {
  1162. return when(callback(), function () {
  1163. return value;
  1164. });
  1165. }, function (exception) {
  1166. return when(callback(), function () {
  1167. return reject(exception);
  1168. });
  1169. });
  1170. }
  1171. /**
  1172. * Terminates a chain of promises, forcing rejections to be
  1173. * thrown as exceptions.
  1174. * @param {Any*} promise at the end of a chain of promises
  1175. * @returns nothing
  1176. */
  1177. Q.done = done;
  1178. function done(promise, fulfilled, rejected, progress) {
  1179. var onUnhandledError = function (error) {
  1180. // forward to a future turn so that ``when``
  1181. // does not catch it and turn it into a rejection.
  1182. nextTick(function () {
  1183. makeStackTraceLong(error, promise);
  1184. if (Q.onerror) {
  1185. Q.onerror(error);
  1186. } else {
  1187. throw error;
  1188. }
  1189. });
  1190. };
  1191. // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
  1192. var promiseToHandle = fulfilled || rejected || progress ?
  1193. when(promise, fulfilled, rejected, progress) :
  1194. promise;
  1195. if (typeof process === "object" && process && process.domain) {
  1196. onUnhandledError = process.domain.bind(onUnhandledError);
  1197. }
  1198. fail(promiseToHandle, onUnhandledError);
  1199. }
  1200. /**
  1201. * Causes a promise to be rejected if it does not get fulfilled before
  1202. * some milliseconds time out.
  1203. * @param {Any*} promise
  1204. * @param {Number} milliseconds timeout
  1205. * @param {String} custom error message (optional)
  1206. * @returns a promise for the resolution of the given promise if it is
  1207. * fulfilled before the timeout, otherwise rejected.
  1208. */
  1209. Q.timeout = timeout;
  1210. function timeout(promise, ms, msg) {
  1211. var deferred = defer();
  1212. var timeoutId = setTimeout(function () {
  1213. deferred.reject(new Error(msg || "Timed out after " + ms + " ms"));
  1214. }, ms);
  1215. when(promise, function (value) {
  1216. clearTimeout(timeoutId);
  1217. deferred.resolve(value);
  1218. }, function (exception) {
  1219. clearTimeout(timeoutId);
  1220. deferred.reject(exception);
  1221. }, deferred.notify);
  1222. return deferred.promise;
  1223. }
  1224. /**
  1225. * Returns a promise for the given value (or promised value) after some
  1226. * milliseconds.
  1227. * @param {Any*} promise
  1228. * @param {Number} milliseconds
  1229. * @returns a promise for the resolution of the given promise after some
  1230. * time has elapsed.
  1231. */
  1232. Q.delay = delay;
  1233. function delay(promise, timeout) {
  1234. if (timeout === void 0) {
  1235. timeout = promise;
  1236. promise = void 0;
  1237. }
  1238. var deferred = defer();
  1239. when(promise, undefined, undefined, deferred.notify);
  1240. setTimeout(function () {
  1241. deferred.resolve(promise);
  1242. }, timeout);
  1243. return deferred.promise;
  1244. }
  1245. /**
  1246. * Passes a continuation to a Node function, which is called with the given
  1247. * arguments provided as an array, and returns a promise.
  1248. *
  1249. * Q.nfapply(FS.readFile, [__filename])
  1250. * .then(function (content) {
  1251. * })
  1252. *
  1253. */
  1254. Q.nfapply = nfapply;
  1255. function nfapply(callback, args) {
  1256. var nodeArgs = array_slice(args);
  1257. var deferred = defer();
  1258. nodeArgs.push(deferred.makeNodeResolver());
  1259. fapply(callback, nodeArgs).fail(deferred.reject);
  1260. return deferred.promise;
  1261. }
  1262. /**
  1263. * Passes a continuation to a Node function, which is called with the given
  1264. * arguments provided individually, and returns a promise.
  1265. *
  1266. * Q.nfcall(FS.readFile, __filename)
  1267. * .then(function (content) {
  1268. * })
  1269. *
  1270. */
  1271. Q.nfcall = nfcall;
  1272. function nfcall(callback/*, ...args */) {
  1273. var nodeArgs = array_slice(arguments, 1);
  1274. var deferred = defer();
  1275. nodeArgs.push(deferred.makeNodeResolver());
  1276. fapply(callback, nodeArgs).fail(deferred.reject);
  1277. return deferred.promise;
  1278. }
  1279. /**
  1280. * Wraps a NodeJS continuation passing function and returns an equivalent
  1281. * version that returns a promise.
  1282. *
  1283. * Q.nfbind(FS.readFile, __filename)("utf-8")
  1284. * .then(console.log)
  1285. * .done()
  1286. *
  1287. */
  1288. Q.nfbind = nfbind;
  1289. Q.denodeify = Q.nfbind; // synonyms
  1290. function nfbind(callback/*, ...args */) {
  1291. var baseArgs = array_slice(arguments, 1);
  1292. return function () {
  1293. var nodeArgs = baseArgs.concat(array_slice(arguments));
  1294. var deferred = defer();
  1295. nodeArgs.push(deferred.makeNodeResolver());
  1296. fapply(callback, nodeArgs).fail(deferred.reject);
  1297. return deferred.promise;
  1298. };
  1299. }
  1300. Q.nbind = nbind;
  1301. function nbind(callback, thisArg /*, ... args*/) {
  1302. var baseArgs = array_slice(arguments, 2);
  1303. return function () {
  1304. var nodeArgs = baseArgs.concat(array_slice(arguments));
  1305. var deferred = defer();
  1306. nodeArgs.push(deferred.makeNodeResolver());
  1307. function bound() {
  1308. return callback.apply(thisArg, arguments);
  1309. }
  1310. fapply(bound, nodeArgs).fail(deferred.reject);
  1311. return deferred.promise;
  1312. };
  1313. }
  1314. /**
  1315. * Calls a method of a Node-style object that accepts a Node-style
  1316. * callback with a given array of arguments, plus a provided callback.
  1317. * @param object an object that has the named method
  1318. * @param {String} name name of the method of object
  1319. * @param {Array} args arguments to pass to the method; the callback
  1320. * will be provided by Q and appended to these arguments.
  1321. * @returns a promise for the value or error
  1322. */
  1323. Q.npost = npost;
  1324. function npost(object, name, args) {
  1325. var nodeArgs = array_slice(args || []);
  1326. var deferred = defer();
  1327. nodeArgs.push(deferred.makeNodeResolver());
  1328. post(object, name, nodeArgs).fail(deferred.reject);
  1329. return deferred.promise;
  1330. }
  1331. /**
  1332. * Calls a method of a Node-style object that accepts a Node-style
  1333. * callback, forwarding the given variadic arguments, plus a provided
  1334. * callback argument.
  1335. * @param object an object that has the named method
  1336. * @param {String} name name of the method of object
  1337. * @param ...args arguments to pass to the method; the callback will
  1338. * be provided by Q and appended to these arguments.
  1339. * @returns a promise for the value or error
  1340. */
  1341. Q.nsend = nsend;
  1342. Q.ninvoke = Q.nsend; // synonyms
  1343. function nsend(object, name /*, ...args*/) {
  1344. var nodeArgs = array_slice(arguments, 2);
  1345. var deferred = defer();
  1346. nodeArgs.push(deferred.makeNodeResolver());
  1347. post(object, name, nodeArgs).fail(deferred.reject);
  1348. return deferred.promise;
  1349. }
  1350. Q.nodeify = nodeify;
  1351. function nodeify(promise, nodeback) {
  1352. if (nodeback) {
  1353. promise.then(function (value) {
  1354. nextTick(function () {
  1355. nodeback(null, value);
  1356. });
  1357. }, function (error) {
  1358. nextTick(function () {
  1359. nodeback(error);
  1360. });
  1361. });
  1362. } else {
  1363. return promise;
  1364. }
  1365. }
  1366. // All code before this point will be filtered from stack traces.
  1367. var qEndingLine = captureLine();
  1368. return Q;
  1369. });