1 [![Build Status](https://secure.travis-ci.org/kriskowal/q.png?branch=master)](http://travis-ci.org/kriskowal/q)
3 <a href="http://promises-aplus.github.com/promises-spec">
4 <img src="http://kriskowal.github.io/q/q.png"
5 align="right" alt="Q logo" />
8 *This is Q version 1, from the `v1` branch in Git. This documentation applies to
9 the latest of both the version 1 and version 0.9 release trains. These releases
10 are stable. There will be no further releases of 0.9 after 0.9.7 which is nearly
11 equivalent to version 1.0.0. All further releases of `q@~1.0` will be backward
12 compatible. The version 2 release train introduces significant and
13 backward-incompatible changes and is experimental at this time.*
15 If a function cannot return a value or throw an exception without
16 blocking, it can return a promise instead. A promise is an object
17 that represents the return value or the thrown exception that the
18 function may eventually provide. A promise can also be used as a
19 proxy for a [remote object][Q-Connection] to overcome latency.
21 [Q-Connection]: https://github.com/kriskowal/q-connection
23 On the first pass, promises can mitigate the “[Pyramid of
24 Doom][POD]”: the situation where code marches to the right faster
25 than it marches forward.
27 [POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/
30 step1(function (value1) {
31 step2(value1, function(value2) {
32 step3(value2, function(value3) {
33 step4(value3, function(value4) {
34 // Do something with value4
41 With a promise library, you can flatten the pyramid.
44 Q.fcall(promisedStep1)
48 .then(function (value4) {
49 // Do something with value4
51 .catch(function (error) {
52 // Handle any error from all above steps
57 With this approach, you also get implicit error propagation, just like `try`,
58 `catch`, and `finally`. An error in `promisedStep1` will flow all the way to
59 the `catch` function, where it’s caught and handled. (Here `promisedStepN` is
60 a version of `stepN` that returns a promise.)
62 The callback approach is called an “inversion of control”.
63 A function that accepts a callback instead of a return value
64 is saying, “Don’t call me, I’ll call you.”. Promises
65 [un-invert][IOC] the inversion, cleanly separating the input
66 arguments from control flow arguments. This simplifies the
67 use and creation of API’s, particularly variadic,
68 rest and spread arguments.
70 [IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
75 The Q module can be loaded as:
77 - A ``<script>`` tag (creating a ``Q`` global variable): ~2.5 KB minified and
79 - A Node.js and CommonJS module, available in [npm](https://npmjs.org/) as
80 the [q](https://npmjs.org/package/q) package
82 - A [component](https://github.com/component/component) as ``microjs/q``
83 - Using [bower](http://bower.io/) as `q#1.0.1`
84 - Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)
86 Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more.
90 Our [wiki][] contains a number of useful resources, including:
92 - A method-by-method [Q API reference][reference].
93 - A growing [examples gallery][examples], showing how Q can be used to make
94 everything better. From XHR to database access to accessing the Flickr API,
96 - There are many libraries that produce and consume Q promises for everything
97 from file system/database access or RPC to templating. For a list of some of
98 the more popular ones, see [Libraries][].
99 - If you want materials that introduce the promise concept generally, and the
100 below tutorial isn't doing it for you, check out our collection of
101 [presentations, blog posts, and podcasts][resources].
102 - A guide for those [coming from jQuery's `$.Deferred`][jquery].
104 We'd also love to have you join the Q-Continuum [mailing list][].
106 [wiki]: https://github.com/kriskowal/q/wiki
107 [reference]: https://github.com/kriskowal/q/wiki/API-Reference
108 [examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery
109 [Libraries]: https://github.com/kriskowal/q/wiki/Libraries
110 [resources]: https://github.com/kriskowal/q/wiki/General-Promise-Resources
111 [jquery]: https://github.com/kriskowal/q/wiki/Coming-from-jQuery
112 [mailing list]: https://groups.google.com/forum/#!forum/q-continuum
117 Promises have a ``then`` method, which you can use to get the eventual
118 return value (fulfillment) or thrown exception (rejection).
122 .then(function (value) {
123 }, function (reason) {
127 If ``promiseMeSomething`` returns a promise that gets fulfilled later
128 with a return value, the first function (the fulfillment handler) will be
129 called with the value. However, if the ``promiseMeSomething`` function
130 gets rejected later by a thrown exception, the second function (the
131 rejection handler) will be called with the exception.
133 Note that resolution of a promise is always asynchronous: that is, the
134 fulfillment or rejection handler will always be called in the next turn of the
135 event loop (i.e. `process.nextTick` in Node). This gives you a nice
136 guarantee when mentally tracing the flow of your code, namely that
137 ``then`` will always return before either handler is executed.
139 In this tutorial, we begin with how to consume and work with promises. We'll
140 talk about how to create them, and thus create functions like
141 `promiseMeSomething` that return promises, [below](#the-beginning).
146 The ``then`` method returns a promise, which in this example, I’m
147 assigning to ``outputPromise``.
150 var outputPromise = getInputPromise()
151 .then(function (input) {
152 }, function (reason) {
156 The ``outputPromise`` variable becomes a new promise for the return
157 value of either handler. Since a function can only either return a
158 value or throw an exception, only one handler will ever be called and it
159 will be responsible for resolving ``outputPromise``.
161 - If you return a value in a handler, ``outputPromise`` will get
164 - If you throw an exception in a handler, ``outputPromise`` will get
167 - If you return a **promise** in a handler, ``outputPromise`` will
168 “become” that promise. Being able to become a new promise is useful
169 for managing delays, combining results, or recovering from errors.
171 If the ``getInputPromise()`` promise gets rejected and you omit the
172 rejection handler, the **error** will go to ``outputPromise``:
175 var outputPromise = getInputPromise()
176 .then(function (value) {
180 If the input promise gets fulfilled and you omit the fulfillment handler, the
181 **value** will go to ``outputPromise``:
184 var outputPromise = getInputPromise()
185 .then(null, function (error) {
189 Q promises provide a ``fail`` shorthand for ``then`` when you are only
190 interested in handling the error:
193 var outputPromise = getInputPromise()
194 .fail(function (error) {
198 If you are writing JavaScript for modern engines only or using
199 CoffeeScript, you may use `catch` instead of `fail`.
201 Promises also have a ``fin`` function that is like a ``finally`` clause.
202 The final handler gets called, with no arguments, when the promise
203 returned by ``getInputPromise()`` either returns a value or throws an
204 error. The value returned or error thrown by ``getInputPromise()``
205 passes directly to ``outputPromise`` unless the final handler fails, and
206 may be delayed if the final handler returns a promise.
209 var outputPromise = getInputPromise()
211 // close files, database connections, stop servers, conclude tests
215 - If the handler returns a value, the value is ignored
216 - If the handler throws an error, the error passes to ``outputPromise``
217 - If the handler returns a promise, ``outputPromise`` gets postponed. The
218 eventual value or error has the same effect as an immediate return
219 value or thrown error: a value would be ignored, an error would be
222 If you are writing JavaScript for modern engines only or using
223 CoffeeScript, you may use `finally` instead of `fin`.
227 There are two ways to chain promises. You can chain promises either
228 inside or outside handlers. The next two examples are equivalent.
232 .then(function (username) {
233 return getUser(username)
234 .then(function (user) {
235 // if we get here without an error,
236 // the value returned here
237 // or the exception thrown here
238 // resolves the promise returned
246 .then(function (username) {
247 return getUser(username);
249 .then(function (user) {
250 // if we get here without an error,
251 // the value returned here
252 // or the exception thrown here
253 // resolves the promise returned
258 The only difference is nesting. It’s useful to nest handlers if you
259 need to capture multiple input values in your closure.
262 function authenticate() {
264 .then(function (username) {
265 return getUser(username);
267 // chained because we will not need the user name in the next event
268 .then(function (user) {
270 // nested because we need both user and password next
271 .then(function (password) {
272 if (user.passwordHash !== hash(password)) {
273 throw new Error("Can't authenticate");
283 You can turn an array of promises into a promise for the whole,
284 fulfilled array using ``all``.
293 If you have a promise for an array, you can use ``spread`` as a
294 replacement for ``then``. The ``spread`` function “spreads” the
295 values over the arguments of the fulfillment handler. The rejection handler
296 will get called at the first sign of failure. That is, whichever of
297 the received promises fails first gets handled by the rejection handler.
300 function eventualAdd(a, b) {
301 return Q.spread([a, b], function (a, b) {
307 But ``spread`` calls ``all`` initially, so you can skip it in chains.
311 .then(function (username) {
312 return [username, getUser(username)];
314 .spread(function (username, user) {
318 The ``all`` function returns a promise for an array of values. When this
319 promise is fulfilled, the array contains the fulfillment values of the original
320 promises, in the same order as those promises. If one of the given promises
321 is rejected, the returned promise is immediately rejected, not waiting for the
322 rest of the batch. If you want to wait for all of the promises to either be
323 fulfilled or rejected, you can use ``allSettled``.
326 Q.allSettled(promises)
327 .then(function (results) {
328 results.forEach(function (result) {
329 if (result.state === "fulfilled") {
330 var value = result.value;
332 var reason = result.reason;
338 The ``any`` function accepts an array of promises and returns a promise that is
339 fulfilled by the first given promise to be fulfilled, or rejected if all of the
340 given promises are rejected.
344 .then(function (first) {
345 // Any of the promises was fulfilled.
346 }, function (error) {
347 // All of the promises were rejected.
353 If you have a number of promise-producing functions that need
354 to be run sequentially, you can of course do so manually:
357 return foo(initialVal).then(bar).then(baz).then(qux);
360 However, if you want to run a dynamically constructed sequence of
361 functions, you'll want something like this:
364 var funcs = [foo, bar, baz, qux];
366 var result = Q(initialVal);
367 funcs.forEach(function (f) {
368 result = result.then(f);
373 You can make this slightly more compact using `reduce`:
376 return funcs.reduce(function (soFar, f) {
377 return soFar.then(f);
381 Or, you could use the ultra-compact version:
384 return funcs.reduce(Q.when, Q(initialVal));
389 One sometimes-unintuive aspect of promises is that if you throw an
390 exception in the fulfillment handler, it will not be caught by the error
395 .then(function (value) {
396 throw new Error("Can't bar.");
397 }, function (error) {
398 // We only get here if "foo" fails
402 To see why this is, consider the parallel between promises and
403 ``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error
404 handler represents a ``catch`` for ``foo()``, while the fulfillment handler
405 represents code that happens *after* the ``try``/``catch`` block.
406 That code then needs its own ``try``/``catch`` block.
408 In terms of promises, this means chaining your rejection handler:
412 .then(function (value) {
413 throw new Error("Can't bar.");
415 .fail(function (error) {
416 // We get here with either foo's error or bar's error
420 ### Progress Notification
422 It's possible for promises to report their progress, e.g. for tasks that take a
423 long time like a file upload. Not all promises will implement progress
424 notifications, but for those that do, you can consume the progress values using
425 a third parameter to ``then``:
430 // Success uploading the file
432 // There was an error, and we get the reason for error
433 }, function (progress) {
434 // We get notified of the upload's progress as it is executed
438 Like `fail`, Q also provides a shorthand for progress callbacks
442 return uploadFile().progress(function (progress) {
443 // We get notified of the upload's progress
449 When you get to the end of a chain of promises, you should either
450 return the last promise or end the chain. Since handlers catch
451 errors, it’s an unfortunate pattern that the exceptions can go
454 So, either return it,
473 Ending a promise chain makes sure that, if an error doesn’t get
474 handled before the end, it will get rethrown and reported.
476 This is a stopgap. We are exploring ways to make unhandled errors
477 visible without any explicit handling.
482 Everything above assumes you get a promise from somewhere else. This
483 is the common case. Every once in a while, you will need to create a
484 promise from scratch.
486 #### Using ``Q.fcall``
488 You can create a promise from a value using ``Q.fcall``. This returns a
492 return Q.fcall(function () {
497 You can also use ``fcall`` to get a promise for an exception.
500 return Q.fcall(function () {
501 throw new Error("Can't do it");
505 As the name implies, ``fcall`` can call functions, or even promised
506 functions. This uses the ``eventualAdd`` function above to add two
510 return Q.fcall(eventualAdd, 2, 2);
516 If you have to interface with asynchronous functions that are callback-based
517 instead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and
518 friends). But much of the time, the solution will be to use *deferreds*.
521 var deferred = Q.defer();
522 FS.readFile("foo.txt", "utf-8", function (error, text) {
524 deferred.reject(new Error(error));
526 deferred.resolve(text);
529 return deferred.promise;
532 Note that a deferred can be resolved with a value or a promise. The
533 ``reject`` function is a shorthand for resolving with a rejected
538 deferred.reject(new Error("Can't do it"));
541 var rejection = Q.fcall(function () {
542 throw new Error("Can't do it");
544 deferred.resolve(rejection);
547 This is a simplified implementation of ``Q.delay``.
551 var deferred = Q.defer();
552 setTimeout(deferred.resolve, ms);
553 return deferred.promise;
557 This is a simplified implementation of ``Q.timeout``
560 function timeout(promise, ms) {
561 var deferred = Q.defer();
562 Q.when(promise, deferred.resolve);
563 delay(ms).then(function () {
564 deferred.reject(new Error("Timed out"));
566 return deferred.promise;
570 Finally, you can send a progress notification to the promise with
573 For illustration, this is a wrapper for XML HTTP requests in the browser. Note
574 that a more [thorough][XHR] implementation would be in order in practice.
576 [XHR]: https://github.com/montagejs/mr/blob/71e8df99bb4f0584985accd6f2801ef3015b9763/browser.js#L29-L73
579 function requestOkText(url) {
580 var request = new XMLHttpRequest();
581 var deferred = Q.defer();
583 request.open("GET", url, true);
584 request.onload = onload;
585 request.onerror = onerror;
586 request.onprogress = onprogress;
590 if (request.status === 200) {
591 deferred.resolve(request.responseText);
593 deferred.reject(new Error("Status code was " + request.status));
598 deferred.reject(new Error("Can't XHR " + JSON.stringify(url)));
601 function onprogress(event) {
602 deferred.notify(event.loaded / event.total);
605 return deferred.promise;
609 Below is an example of how to use this ``requestOkText`` function:
612 requestOkText("http://localhost:3000")
613 .then(function (responseText) {
614 // If the HTTP response returns 200 OK, log the response text.
615 console.log(responseText);
616 }, function (error) {
617 // If there's an error or a non-200 status code, log the error.
618 console.error(error);
619 }, function (progress) {
620 // Log the progress as it comes in.
621 console.log("Request progress: " + Math.round(progress * 100) + "%");
625 #### Using `Q.Promise`
627 This is an alternative promise-creation API that has the same power as
628 the deferred concept, but without introducing another conceptual entity.
630 Rewriting the `requestOkText` example above using `Q.Promise`:
633 function requestOkText(url) {
634 return Q.Promise(function(resolve, reject, notify) {
635 var request = new XMLHttpRequest();
637 request.open("GET", url, true);
638 request.onload = onload;
639 request.onerror = onerror;
640 request.onprogress = onprogress;
644 if (request.status === 200) {
645 resolve(request.responseText);
647 reject(new Error("Status code was " + request.status));
652 reject(new Error("Can't XHR " + JSON.stringify(url)));
655 function onprogress(event) {
656 notify(event.loaded / event.total);
662 If `requestOkText` were to throw an exception, the returned promise would be
663 rejected with that thrown exception as the rejection reason.
667 If you are using a function that may return a promise, but just might
668 return a value if it doesn’t need to defer, you can use the “static”
669 methods of the Q library.
671 The ``when`` function is the static equivalent for ``then``.
674 return Q.when(valueOrPromise, function (value) {
675 }, function (error) {
679 All of the other methods on a promise have static analogs with the
682 The following are equivalent:
685 return Q.all([a, b]);
689 return Q.fcall(function () {
695 When working with promises provided by other libraries, you should
696 convert it to a Q promise. Not all promise libraries make the same
697 guarantees as Q and certainly don’t provide all of the same methods.
698 Most libraries only provide a partially functional ``then`` method.
699 This thankfully is all we need to turn them into vibrant Q promises.
702 return Q($.ajax(...))
707 If there is any chance that the promise you receive is not a Q promise
708 as provided by your library, you should wrap it using a Q function.
709 You can even use ``Q.invoke`` as a shorthand.
712 return Q.invoke($, 'ajax', ...)
720 A promise can serve as a proxy for another object, even a remote
721 object. There are methods that allow you to optimistically manipulate
722 properties or call functions. All of these interactions return
723 promises, so they can be chained.
726 direct manipulation using a promise as a proxy
727 -------------------------- -------------------------------
728 value.foo promise.get("foo")
729 value.foo = value promise.put("foo", value)
730 delete value.foo promise.del("foo")
731 value.foo(...args) promise.post("foo", [args])
732 value.foo(...args) promise.invoke("foo", ...args)
733 value(...args) promise.fapply([args])
734 value(...args) promise.fcall(...args)
737 If the promise is a proxy for a remote object, you can shave
738 round-trips by using these functions instead of ``then``. To take
739 advantage of promises for remote objects, check out [Q-Connection][].
741 [Q-Connection]: https://github.com/kriskowal/q-connection
743 Even in the case of non-remote objects, these methods can be used as
744 shorthand for particularly-simple fulfillment handlers. For example, you
748 return Q.fcall(function () {
749 return [{ foo: "bar" }, { foo: "baz" }];
751 .then(function (value) {
759 return Q.fcall(function () {
760 return [{ foo: "bar" }, { foo: "baz" }];
769 If you're working with functions that make use of the Node.js callback pattern,
770 where callbacks are in the form of `function(err, result)`, Q provides a few
771 useful utility functions for converting between them. The most straightforward
772 are probably `Q.nfcall` and `Q.nfapply` ("Node function call/apply") for calling
773 Node.js-style functions and getting back a promise:
776 return Q.nfcall(FS.readFile, "foo.txt", "utf-8");
777 return Q.nfapply(FS.readFile, ["foo.txt", "utf-8"]);
780 If you are working with methods, instead of simple functions, you can easily
781 run in to the usual problems where passing a method to another function—like
782 `Q.nfcall`—"un-binds" the method from its owner. To avoid this, you can either
783 use `Function.prototype.bind` or some nice shortcut methods we provide:
786 return Q.ninvoke(redisClient, "get", "user:1:id");
787 return Q.npost(redisClient, "get", ["user:1:id"]);
790 You can also create reusable wrappers with `Q.denodeify` or `Q.nbind`:
793 var readFile = Q.denodeify(FS.readFile);
794 return readFile("foo.txt", "utf-8");
796 var redisClientGet = Q.nbind(redisClient.get, redisClient);
797 return redisClientGet("user:1:id");
800 Finally, if you're working with raw deferred objects, there is a
801 `makeNodeResolver` method on deferreds that can be handy:
804 var deferred = Q.defer();
805 FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver());
806 return deferred.promise;
809 ### Long Stack Traces
811 Q comes with optional support for “long stack traces,” wherein the `stack`
812 property of `Error` rejection reasons is rewritten to be traced along
813 asynchronous jumps instead of stopping at the most recent one. As an example:
816 function theDepthsOfMyProgram() {
817 Q.delay(100).done(function explode() {
818 throw new Error("boo!");
822 theDepthsOfMyProgram();
825 usually would give a rather unhelpful stack trace looking something like
829 at explode (/path/to/test.js:3:11)
830 at _fulfilled (/path/to/test.js:q:54)
831 at resolvedValue.promiseDispatch.done (/path/to/q.js:823:30)
832 at makePromise.promise.promiseDispatch (/path/to/q.js:496:13)
833 at pending (/path/to/q.js:397:39)
834 at process.startup.processNextTick.process._tickCallback (node.js:244:9)
837 But, if you turn this feature on by setting
840 Q.longStackSupport = true;
843 then the above code gives a nice stack trace to the tune of
847 at explode (/path/to/test.js:3:11)
849 at theDepthsOfMyProgram (/path/to/test.js:2:16)
850 at Object.<anonymous> (/path/to/test.js:7:1)
853 Note how you can see the function that triggered the async operation in the
854 stack trace! This is very helpful for debugging, as otherwise you end up getting
855 only the first line, plus a bunch of Q internals, with no sign of where the
858 In node.js, this feature can also be enabled through the Q_DEBUG environment
862 Q_DEBUG=1 node server.js
865 This will enable long stack support in every instance of Q.
867 This feature does come with somewhat-serious performance and memory overhead,
868 however. If you're working with lots of promises, or trying to scale a server
869 to many users, you should probably keep it off. But in development, go for it!
873 You can view the results of the Q test suite [in your browser][tests]!
875 [tests]: https://rawgithub.com/kriskowal/q/v1/spec/q-spec.html
879 Copyright 2009–2015 Kristopher Michael Kowal and contributors
880 MIT License (enclosed)