-
Notifications
You must be signed in to change notification settings - Fork 1
/
package.json
executable file
·88 lines (88 loc) · 19.2 KB
/
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{
"name": "q",
"version": "0.8.12",
"description": "A library for promises (CommonJS/Promises/A,B,D)",
"homepage": "https://github.com/kriskowal/q",
"author": {
"name": "Kris Kowal",
"email": "kris@cixar.com",
"url": "https://github.com/kriskowal"
},
"keywords": [
"q",
"promise",
"promises",
"promises-a",
"promises-a-plus",
"deferred",
"future",
"async",
"flow control",
"fluent",
"browser",
"node"
],
"contributors": [
{
"name": "Kris Kowal",
"email": "kris@cixar.com",
"url": "https://github.com/kriskowal"
},
{
"name": "Irakli Gozalishvili",
"email": "rfobic@gmail.com",
"url": "http://jeditoolkit.com"
},
{
"name": "Domenic Denicola",
"email": "domenic@domenicdenicola.com",
"url": "http://domenicdenicola.com"
}
],
"bugs": {
"url": "http://github.com/kriskowal/q/issues"
},
"licenses": [
{
"type": "MIT",
"url": "http://github.com/kriskowal/q/raw/master/LICENSE"
}
],
"main": "q.js",
"repository": {
"type": "git",
"url": "git://github.com/kriskowal/q.git"
},
"engines": {
"node": ">=0.6.0",
"teleport": ">=0.2.0"
},
"dependencies": {},
"devDependencies": {
"jshint": ">=0.9.1",
"cover": "*",
"jasmine-node": "*",
"opener": "*",
"promises-aplus-tests": "~1.0"
},
"scripts": {
"test": "jasmine-node spec && promises-aplus-tests spec/aplus-adapter",
"test-browser": "opener spec/q-spec.html",
"lint": "jshint q.js",
"cover": "cover run node_modules/jasmine-node/bin/jasmine-node spec && cover report html && opener cover_html/index.html"
},
"overlay": {
"teleport": {
"dependencies": {
"system": ">=0.0.4"
}
}
},
"directories": {
"test": "./spec"
},
"readme": "[![Build Status](https://secure.travis-ci.org/kriskowal/q.png)](http://travis-ci.org/kriskowal/q)\n\n<a href=\"http://promises-aplus.github.com/promises-spec\">\n <img src=\"http://promises-aplus.github.com/promises-spec/assets/logo-small.png\"\n align=\"right\" alt=\"Promises/A+ logo\" />\n</a>\n\nIf a function cannot return a value or throw an exception without\nblocking, it can return a promise instead. A promise is an object\nthat represents the return value or the thrown exception that the\nfunction may eventually provide. A promise can also be used as a\nproxy for a [remote object][Q-Connection] to overcome latency.\n\n[Q-Connection]: https://github.com/kriskowal/q-connection\n\nOn the first pass, promises can mitigate the “[Pyramid of\nDoom][POD]”: the situation where code marches to the right faster\nthan it marches forward.\n\n[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/\n\n```javascript\nstep1(function (value1) {\n step2(value1, function(value2) {\n step3(value2, function(value3) {\n step4(value3, function(value4) {\n // Do something with value4\n });\n });\n });\n});\n```\n\nWith a promise library, you can flatten the pyramid.\n\n```javascript\nQ.fcall(step1)\n.then(step2)\n.then(step3)\n.then(step4)\n.then(function (value4) {\n // Do something with value4\n}, function (error) {\n // Handle any error from step1 through step4\n})\n.done();\n```\n\nWith this approach, you also get implicit error propagation,\njust like ``try``, ``catch``, and ``finally``. An error in\n``step1`` will flow all the way to ``step5``, where it’s\ncaught and handled.\n\nThe callback approach is called an “inversion of control”.\nA function that accepts a callback instead of a return value\nis saying, “Don’t call me, I’ll call you.”. Promises\n[un-invert][IOC] the inversion, cleanly separating the input\narguments from control flow arguments. This simplifies the\nuse and creation of API’s, particularly variadic,\nrest and spread arguments.\n\n[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript\n\n\n## Getting Started\n\nThe Q module can be loaded as:\n\n- a ``<script>`` tag (creating a ``Q`` global variable):\n ~3.5 KB minified and gzipped.\n- a Node.js and CommonJS module available from NPM as the ``q``\n package\n- a RequireJS module\n\nQ can exchange promises with jQuery, Dojo, When.js, WinJS, and more.\nAdditionally, there are many libraries that produce and consume Q promises for\neverything from file system/database access or RPC to templating. For a list of\nsome of the more popular ones, see [Libraries][].\n\nPlease join the Q-Continuum [mailing list](https://groups.google.com/forum/#!forum/q-continuum).\n\n[Libraries]: https://github.com/kriskowal/q/wiki/Libraries\n\n\n## Tutorial\n\nPromises have a ``then`` method, which you can use to get the eventual\nreturn value (fulfillment) or thrown exception (rejection).\n\n```javascript\nfoo()\n.then(function (value) {\n}, function (reason) {\n})\n```\n\nIf ``foo`` returns a promise that gets fulfilled later with a return\nvalue, the first function (the value handler) will be called with the\nvalue. However, if the ``foo`` function gets rejected later by a\nthrown exception, the second function (the error handler) will be\ncalled with the error.\n\nNote that resolution of a promise is always asynchronous: that is, the\nvalue or error handler will always be called in the next turn of the\nevent loop (i.e. `process.nextTick` in Node). This gives you a nice\nguarantee when mentally tracing the flow of your code, namely that\n``then`` will always return before either handler is executed.\n\n\n### Propagation\n\nThe ``then`` method returns a promise, which in this example, I’m\nassigning to ``bar``.\n\n```javascript\nvar bar = foo()\n.then(function (value) {\n}, function (reason) {\n})\n```\n\nThe ``bar`` variable becomes a new promise for the return value of\neither handler. Since a function can only either return a value or\nthrow an exception, only one handler will ever be called and it will\nbe responsible for resolving ``bar``.\n\n- If you return a value in a handler, ``bar`` will get fulfilled.\n\n- If you throw an exception in a handler ``bar`` will get rejected.\n\n- If you return a **promise** in a handler, ``bar`` will “become”\n that promise. Being able to become a new promise is useful for\n managing delays, combining results, or recovering from errors.\n\nIf the ``foo()`` promise gets rejected and you omit the error handler,\nthe **error** will go to ``bar``:\n\n```javascript\nvar bar = foo()\n.then(function (value) {\n})\n```\n\nIf the ``foo()`` promise gets fulfilled and you omit the value\nhandler, the **value** will go to ``bar``:\n\n```javascript\nvar bar = foo()\n.then(null, function (error) {\n})\n```\n\nQ promises provide a ``fail`` shorthand for ``then`` when you are only\ninterested in handling the error:\n\n```javascript\nvar bar = foo()\n.fail(function (error) {\n})\n```\n\nThey also have a ``fin`` function that is like a ``finally`` clause.\nThe final handler gets called, with no arguments, when the promise\nreturned by ``foo()`` either returns a value or throws an error. The\nvalue returned or error thrown by ``foo()`` passes directly to ``bar``.\n\n```javascript\nvar bar = foo()\n.fin(function () {\n // close files, database connections, stop servers, conclude tests\n})\n```\n\n- If the handler returns a value, the value is ignored\n- If the handler throws an error, the error passes to ``bar``\n- If the handler returns a promise, ``bar`` gets postponed. The\n eventual value or error has the same effect as an immediate return\n value or thrown error: a value would be ignored, an error would be\n forwarded.\n\n### Chaining\n\nThere are two ways to chain promises. You can chain promises either\ninside or outside handlers. The next two examples are equivalent.\n\n```javascript\nreturn foo()\n.then(function (fooValue) {\n return bar(fooValue)\n .then(function (barValue) {\n // if we get here without an error,\n // the value returned here\n // or the exception thrown here\n // resolves the promise returned\n // by the first line\n })\n})\n```\n\n```javascript\nreturn foo()\n.then(function (fooValue) {\n return bar(fooValue);\n})\n.then(function (barValue) {\n // if we get here without an error,\n // the value returned here\n // or the exception thrown here\n // resolves the promise returned\n // by the first line\n})\n```\n\nThe only difference is nesting. It’s useful to nest handlers if you\nneed to capture both ``fooValue`` and ``barValue`` in the last\nhandler.\n\n```javascript\nfunction eventualAdd(a, b) {\n return a.then(function (a) {\n return b.then(function (b) {\n return a + b;\n });\n });\n}\n```\n\n\n### Combination\n\nYou can turn an array of promises into a promise for the whole,\nfulfilled array using ``all``.\n\n```javascript\nreturn Q.all([\n eventualAdd(2, 2),\n eventualAdd(10, 20)\n])\n```\n\nIf you have a promise for an array, you can use ``spread`` as a\nreplacement for ``then``. The ``spread`` function “spreads” the\nvalues over the arguments of the value handler. The error handler\nwill get called at the first sign of failure. That is, whichever of\nthe recived promises fails first gets handled by the error handler.\n\n```javascript\nfunction eventualAdd(a, b) {\n return Q.spread([a, b], function (a, b) {\n return a + b;\n })\n}\n```\n\nBut ``spread`` calls ``all`` initially, so you can skip it in chains.\n\n```javascript\nreturn foo()\n.then(function (info) {\n return [info.name, FS.read(info.location, \"utf-8\")];\n // FS.read returns a promise, so this array\n // mixes values and promises\n})\n.spread(function (name, text) {\n})\n```\n\nThe ``all`` function returns a promise for an array of values. If one\nof the given promise fails, the whole returned promise fails, not\nwaiting for the rest of the batch. If you want to wait for all of the\npromises to either be fulfilled or rejected, you can use\n``allResolved``.\n\n```javascript\nQ.allResolved(promises)\n.then(function (promises) {\n promises.forEach(function (promise) {\n if (promise.isFulfilled()) {\n var value = promise.valueOf();\n } else {\n var exception = promise.valueOf().exception;\n }\n })\n})\n```\n\n\n### Sequences\n\nIf you have a number of promise-producing functions that need\nto be run sequentially, you can of course do so manually:\n\n```javascript\nreturn foo(initialVal).then(bar).then(baz).then(quux);\n```\n\nHowever, if you want to run a dynamically constructed sequence of\nfunctions, you'll want something like this:\n\n```javascript\nvar funcs = [foo, bar, baz, quux];\n\nvar result = Q.resolve(initialVal);\nfuncs.forEach(function (f) {\n result = result.then(f);\n});\nreturn result;\n```\n\nYou can make this slightly more compact using `reduce`:\n\n```javascript\nreturn funcs.reduce(function (soFar, f) {\n return soFar.then(f);\n}, Q.resolve(initialVal));\n```\n\n\n### Handling Errors\n\nOne sometimes-unintuive aspect of promises is that if you throw an\nexception in the value handler, it will not be be caught by the error\nhandler.\n\n```javascript\nfoo()\n.then(function (value) {\n throw new Error(\"Can't bar.\");\n}, function (error) {\n // We only get here if \"foo\" fails\n})\n```\n\nTo see why this is, consider the parallel between promises and\n``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error\nhandler represents a ``catch`` for ``foo()``, while the value handler\nrepresents code that happens *after* the ``try``/``catch`` block.\nThat code then needs its own ``try``/``catch`` block.\n\nIn terms of promises, this means chaining your error handler:\n\n```javascript\nfoo()\n.then(function (value) {\n throw new Error(\"Can't bar.\");\n})\n.fail(function (error) {\n // We get here with either foo's error or bar's error\n})\n```\n\n\n### The End\n\nWhen you get to the end of a chain of promises, you should either\nreturn the last promise or end the chain. Since handlers catch\nerrors, it’s an unfortunate pattern that the exceptions can go\nunobserved.\n\nSo, either return it,\n\n```javascript\nreturn foo()\n.then(function () {\n return \"bar\";\n})\n```\n\nOr, end it.\n\n```javascript\nfoo()\n.then(function () {\n return \"bar\";\n})\n.done()\n```\n\nEnding a promise chain makes sure that, if an error doesn’t get\nhandled before the end, it will get rethrown and reported.\n\nThis is a stopgap. We are exploring ways to make unhandled errors\nvisible without any explicit handling.\n\n\n### The Beginning\n\nEverything above assumes you get a promise from somewhere else. This\nis the common case. Every once in a while, you will need to create a\npromise from scratch.\n\n#### Using ``Q.fcall``\n\nYou can create a promise from a value using ``Q.fcall``. This returns a\npromise for 10.\n\n```javascript\nreturn Q.fcall(function () {\n return 10;\n});\n```\n\nYou can also use ``fcall`` to get a promise for an exception.\n\n```javascript\nreturn Q.fcall(function () {\n throw new Error(\"Can't do it\");\n})\n```\n\nAs the name implies, ``fcall`` can call functions, or even promised\nfunctions. This uses the ``eventualAdd`` function above to add two\nnumbers.\n\n```javascript\nreturn Q.fcall(eventualAdd, 2, 2);\n```\n\n\n#### Using Deferreds\n\nIf you have to interface with asynchronous functions that are callback-based\ninstead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and\nfriends). But much of the time, the solution will be to use *deferreds*.\n\n```javascript\nvar deferred = Q.defer();\nFS.readFile(\"foo.txt\", \"utf-8\", function (error, text) {\n if (error) {\n deferred.reject(new Error(error));\n } else {\n deferred.resolve(text);\n }\n});\nreturn deferred.promise;\n```\n\nNote that a deferred can be resolved with a value or a promise. The\n``reject`` function is a shorthand for resolving with a rejected\npromise.\n\n```javascript\n// this:\ndeferred.reject(new Error(\"Can't do it\"));\n\n// is shorthand for:\nvar rejection = Q.fcall(function () {\n throw new Error(\"Can't do it\");\n});\ndeferred.resolve(rejection);\n```\n\nThis is a simplified implementation of ``Q.delay``.\n\n```javascript\nfunction delay(ms) {\n var deferred = Q.defer();\n setTimeout(deferred.resolve, ms);\n return deferred.promise;\n}\n```\n\nThis is a simplified implementation of ``Q.timeout``\n\n```javascript\nfunction timeout(promise, ms) {\n var deferred = Q.defer();\n Q.when(promise, deferred.resolve);\n Q.when(delay(ms), function () {\n deferred.reject(new Error(\"Timed out\"));\n });\n return deferred.promise;\n}\n```\n\n\n### The Middle\n\nIf you are using a function that may return a promise, but just might\nreturn a value if it doesn’t need to defer, you can use the “static”\nmethods of the Q library.\n\nThe ``when`` function is the static equivalent for ``then``.\n\n```javascript\nreturn Q.when(valueOrPromise, function (value) {\n}, function (error) {\n});\n```\n\nAll of the other methods on a promise have static analogs with the\nsame name.\n\nThe following are equivalent:\n\n```javascript\nreturn Q.all([a, b]);\n```\n\n```javascript\nreturn Q.fcall(function () {\n return [a, b];\n})\n.all();\n```\n\nWhen working with promises provided by other libraries, you should\nconvert it to a Q promise. Not all promise libraries make the same\nguarantees as Q and certainly don’t provide all of the same methods.\nMost libraries only provide a partially functional ``then`` method.\nThis thankfully is all we need to turn them into vibrant Q promises.\n\n```javascript\nreturn Q.when($.ajax(...))\n.then(function () {\n})\n```\n\nIf there is any chance that the promise you receive is not a Q promise\nas provided by your library, you should wrap it using a Q function.\nYou can even use ``Q.invoke`` as a shorthand.\n\n```javascript\nreturn Q.invoke($, 'ajax', ...)\n.then(function () {\n})\n```\n\n\n### Over the Wire\n\nA promise can serve as a proxy for another object, even a remote\nobject. There are methods that allow you to optimistically manipulate\nproperties or call functions. All of these interactions return\npromises, so they can be chained.\n\n```\ndirect manipulation using a promise as a proxy\n-------------------------- -------------------------------\nvalue.foo promise.get(\"foo\")\nvalue.foo = value promise.put(\"foo\", value)\ndelete value.foo promise.del(\"foo\")\nvalue.foo(...args) promise.post(\"foo\", [args])\nvalue.foo(...args) promise.invoke(\"foo\", ...args)\nvalue(...args) promise.fapply([args])\nvalue(...args) promise.fcall(...args)\n```\n\nIf the promise is a proxy for a remote object, you can shave\nround-trips by using these functions instead of ``then``. To take\nadvantage of promises for remote objects, check out [Q-Comm][].\n\n[Q-Comm]: https://github.com/kriskowal/q-comm\n\nEven in the case of non-remote objects, these methods can be used as\nshorthand for particularly-simple value handlers. For example, you\ncan replace\n\n```javascript\nreturn Q.fcall(function () {\n return [{ foo: \"bar\" }, { foo: \"baz\" }];\n})\n.then(function (value) {\n return value[0].foo;\n})\n```\n\nwith\n\n```javascript\nreturn Q.fcall(function () {\n return [{ foo: \"bar\" }, { foo: \"baz\" }];\n})\n.get(0)\n.get(\"foo\")\n```\n\n\n### Adapting Node\n\nThere is a ``makeNodeResolver`` method on deferreds that is handy for\nthe NodeJS callback pattern.\n\n```javascript\nvar deferred = Q.defer();\nFS.readFile(\"foo.txt\", \"utf-8\", deferred.makeNodeResolver());\nreturn deferred.promise;\n```\n\nAnd there are ``Q.nfcall`` and ``Q.ninvoke`` for even shorter\nexpression.\n\n```javascript\nreturn Q.nfcall(FS.readFile, \"foo.txt\", \"utf-8\");\n```\n\n```javascript\nreturn Q.ninvoke(FS, \"readFile\", \"foo.txt\", \"utf-8\");\n```\n\nThere is also a ``Q.nfbind`` function that that creates a reusable\nwrapper.\n\n```javascript\nvar readFile = Q.nfbind(FS.readFile);\nreturn readFile(\"foo.txt\", \"utf-8\");\n```\n\nNote that, since promises are always resolved in the next turn of the\nevent loop, working with streams [can be tricky][streams]. The\nessential problem is that, since Node does not buffer input, it is\nnecessary to attach your ``\"data\"`` event listeners immediately,\nbefore this next turn comes around. There are a variety of solutions\nto this problem, and even some hope that in future versions of Node it\nwill [be ameliorated][streamsnext].\n\n[streams]: https://groups.google.com/d/topic/q-continuum/xr8znxc_K5E/discussion\n[streamsnext]: http://maxogden.com/node-streams#streams.next\n\n## Reference\n\nA method-by-method [Q API reference][reference] is available on the wiki.\n\n[reference]: https://github.com/kriskowal/q/wiki/API-Reference\n\n## More Examples\n\nA growing [examples gallery][examples] is available on the wiki, showing how Q\ncan be used to make everything better. From XHR to database access to accessing\nthe Flickr API, Q is there for you.\n\n[examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery\n\n---\n\nCopyright 2009-2012 Kristopher Michael Kowal\nMIT License (enclosed)\n\n",
"readmeFilename": "README.md",
"_id": "q@0.8.12",
"_from": "q@~0.8.10"
}