blob: 218df3cb519d8f94a464968cdf14d9fb47e8e892 [file] [log] [blame]
{
"name": "q",
"version": "0.7.2",
"description": "A library for promises (CommonJS/Promises/A,B,D)",
"homepage": "http://github.com/kriskowal/q/",
"author": {
"name": "Kris Kowal",
"email": "kris@cixar.com",
"url": "http://github.com/kriskowal/"
},
"contributors": [
{
"name": "Kris Kowal",
"email": "kris@cixar.com",
"url": "http://github.com/kriskowal/"
},
{
"name": "Irakli Gozalishvili",
"email": "rfobic@gmail.com",
"url": "http://jeditoolkit.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": "http://github.com/kriskowal/q.git"
},
"engines": {
"node": ">=0.2.0",
"teleport": ">=0.2.0"
},
"dependencies": {
"event-queue": ">=0.0.1"
},
"devDependencies": {
"uglify-js": ">= 0.0.5",
"test": ">=0.3.0"
},
"scripts": {
"test": "node test/all.js"
},
"overlay": {
"teleport": {
"dependencies": {
"event-queue": ">=0.0.1",
"system": ">=0.0.4"
}
}
},
"directories": {
"test": "./test"
},
"readme": "\nQ is a tool for making and composing asynchronous promises in\nJavaScript.\n\nAn asynchronous promise is an object that represents the eventual\nreturn value (fulfillment) or thrown exception of (rejection) of a\nfunction that could not respond before returning without blocking,\nlike file system, inter-process, and network operations. An eventual\n\"resolution\" is either a fulfillment or a rejection.\n\nThe Q module can be loaded as:\n\n- a ``<script>`` tag (creating a ``Q`` global variable)\n- a NodeJS module, or generally a CommonJS module,\n available from NPM as the ``q`` package.\n- a RequireJS module\n\nWe have a [mailing list].\n\n[mailing list]: https://groups.google.com/forum/#!forum/q-continuum\n\nQ is designed to work well with jQuery, Dojo, and as part of an\necosystem of NodeJS NPM packages, many of which also work in browsers,\nincluding:\n\n- [qq](https://github.com/kriskowal/qq)\n infinite queues, deep and shallow object resolution,\n map/reduce helpers, lazy objects (/!\\ This was\n originally ``q/util`` in this package, but has moved\n into its own home due to changes in NPM 1.)\n- [q-fs](https://github.com/kriskowal/q-fs)\n file system\n- [q-http](https://github.com/kriskowal/q-http)\n http client and server\n- [q-comm](https://github.com/kriskowal/q-comm)\n remote objects\n- [jaque](https://github.com/kriskowal/jaque)\n promising HTTP server, JSGI middleware\n- [teleport](https://github.com/gozala/teleport)\n browser-side module promises\n\nQ conforms to many proposed standards, mostly by Kris Zyp and myself,\nwith mentoring from Mark Miller: [UncommonJS/Promises][]\n[CommonJS/Promises/A][], [CommonJS/Promises/B][], and\n[CommonJS/Promises/D][]. Q is based on Tyler Close's [ref_send][] API\nfor [Waterken][].\n\n[UncommonJS/Promises]: https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md\n[CommonJS/Promises/A]: http://wiki.commonjs.org/wiki/Promises/A\n[CommonJS/Promises/B]: http://wiki.commonjs.org/wiki/Promises/B\n[CommonJS/Promises/D]: http://wiki.commonjs.org/wiki/Promises/D\n[ref_send]: http://waterken.svn.sourceforge.net/viewvc/waterken/server/trunk/waterken/config/file/site/ref_send.js?view=markup\n[Waterken]: http://waterken.sourceforge.net/\n\n\nEXAMPLES\n--------\n\n## ``defer``\n\nThis example provides a promise-oriented ``delay`` function\nbased on the callback-oriented ``setTimeout`` function.\n\n function delay(ms) {\n var deferred = Q.defer();\n setTimeout(deferred.resolve, ms);\n return deferred.promise;\n }\n\n\nThis example takes a promise and returns a promise that will\nbe rejected if the given promise is not fulfilled in a\ntimely fashion.\n\n function timeout(promise, ms) {\n var deferred = Q.defer();\n Q.when(promise, deferred.resolve);\n Q.when(delay(ms), function () {\n deferred.reject(\"Timed out\");\n });\n return deferred.promise;\n }\n\n\nThis example wraps Node's file listing function, returning a\npromise instead of accepting a callback.\n\n var FS = require(\"fs\"); // from Node\n\n function list(path) {\n path = String(path);\n var result = Q.defer();\n FS.readdir(path, function (error, list) {\n if (error)\n return result.reject(error);\n else\n result.resolve(list);\n });\n return result.promise;\n }\n\n\n## ``when``\n\nThis example illustrates how the ``when`` primitive can be\nused to observe the fulfillment of a promise.\n\n var bPromise = Q.when(aPromise, function (aValue) {\n return bValue;\n });\n\n* If ``aPromise`` is fulfilled, the callback is called in a future\n turn of the even loop with the fulfilled value as ``aValue``.\n* If ``aPromise`` is rejected, ``bPromise`` will be resolved with\n ``aPromise`` (the rejection will be forwarded).\n* ``bPromise`` is eventually resolved with ``bValue``.\n* ``aPromise`` does not actually need to be a promise. It can be any\n value, in which case it is treated as an already fulfilled\n promise.\n* ``bValue`` does not actually need to be a value. It can be a\n promise, which would further defer the resolution of ``bPromise``.\n* If the fulfillment callback throws an exception, ``bPromise`` will\n be rejected with the thrown error as the reason.\n\n\nThis example illustrates how the ``when`` primitive can be used to\nobserve either the fulfillment or rejection of a promise. \n\n var bPromise = Q.when(aPromise, function (aValue) {\n return bValue;\n }, function (aReason) {\n return bValue; // or\n throw bReason;\n });\n\n* If ``aPromise`` is rejected, the second callback, the rejection\n callback, will be called with the reason for the rejection as\n ``aReason``.\n* The value returned by the rejection callback will be used to\n resolve ``bPromise``.\n* If the rejection callback throws an error, ``bPromise`` will be\n rejected with the error as the reason.\n* Unlike a ``try`` and ``catch`` block, the rejection callback will not\n be called if the fulfillment callback throws an error or returns a\n rejection. To observe an exception thrown in either the\n fulfillment or the rejection callback, another ``when`` block must\n be used to observe the rejection of ``bPromise``.\n\nIn general,\n\n* If the rejection callback is falsy and ``aPromise`` is rejected, the\n rejection will be forwarded to ``bPromise``.\n* If the fulfillment callback is falsy and ``aPromise`` is fulfilled,\n the fulfilled value will be forwarded to ``bPromise``.\n\n\n## Node File-system Examples\n\nIn Node, this example reads itself and writes itself out in\nall capitals.\n\n var Q = require(\"q\");\n var FS = require(\"q-fs\");\n\n var text = FS.read(__filename);\n Q.when(text, function (text) {\n console.log(text.toUpperCase());\n });\n\nYou can also perform actions in parallel. This example\nreads two files at the same time, waits for both to finish,\nthen logs their lengths.\n\n var Q = require(\"q\");\n var FS = require(\"q-fs\");\n\n var self = FS.read(__filename);\n var passwd = FS.read(\"/etc/passwd\");\n Q.join(self, passwd, function (self, passwd) {\n console.log(__filename + ':', self.length);\n console.log('/etc/passwd:', passwd.length);\n });\n\nThis example reads all of the files in the same directory as\nthe program and notes the length of each, in the order in\nwhich they are finished reading.\n\n var Q = require(\"q\");\n var FS = require(\"q-fs\");\n\n var list = FS.list(__dirname);\n var files = Q.when(list, function (list) {\n list.forEach(function (fileName) {\n var content = FS.read(fileName);\n Q.when(content, function (content) {\n console.log(fileName, content.length);\n });\n });\n });\n\nThis example reads all of the files in the same directory as\nthe program and notes the length of each, in the order in\nwhich they were listed.\n\n var Q = require(\"q\");\n var FS = require(\"q-fs\");\n\n var list = FS.list(__dirname);\n var files = Q.when(list, function (list) {\n return list.reduce(function (ready, fileName) {\n var content = FS.read(fileName);\n return Q.join(ready, content, function (ready, content) {\n console.log(fileName, content.length);\n });\n });\n });\n\n\n## Parallel Join\n\nPromises can be used to do work either in parallel or\nserial, depending on whether you wait for one promise to be\nfulfilled before beginning work on a second. To do a\nparallel join, begin work and get promises and use nested\n``when`` blocks to create a single promise that will be\nresolved when both inputs are resolved, or when the first is\nrejected.\n\n var aPromise = aFunction();\n var bPromise = bFunction();\n var cPromise = Q.when(aPromise, function (aValue) {\n return Q.when(bPromise, function (bValue) {\n return cValue;\n });\n });\n\nFor short, you can use the ``join`` function.\n\n var Q = require(\"q\");\n var aPromise = aFunction();\n var bPromise = bFunction();\n Q.join(aPromise, bPromise, function (aValue, bValue) {\n return cValue;\n });\n\nIf a piece of work can be done on each value in an array in\nparallel, you can use either a ``forEach`` loop or a ``reduce``\nloop to create a ``done`` promise.\n\n var done;\n array.forEach(function (value) {\n var work = doWork(value); \n done = Q.when(done, function () {\n return work;\n });\n });\n return done;\n\nIt is a bit more concise with a ``reduce`` loop.\n\n return array.reduce(function (done, value) {\n var work = doWork(value);\n return Q.when(done, function () {\n return work;\n });\n }, undefined);\n\nYou can also join the promises with a variadic ``wait``\ncall, which is equivalent.\n\n return array.reduce(function (done, value) {\n var work = doWork(value);\n return Q.wait(work, done);\n }, undefined);\n\n\n## Serial Join\n\nIf you have two pieces of work and the second cannot be done\nuntil the first completes, you can also use nested ``when``\nblocks.\n\n var aPromise = aFunction();\n var cPromise = Q.when(aPromise, function (aValue) {\n var bPromise = bFunction(aValue);\n return Q.when(bPromise, function bValue) {\n return cValue;\n });\n });\n\nIf you can do work on each value in an array, but want to do\nthem in order and one at a time, you can use ``forEach`` or\n``reduce`` loop.\n\n var done;\n array.forEach(function (value) {\n done = Q.when(done, function () {\n return doWork(value); \n });\n });\n return done;\n\nIt is more concise with ``reduce`` and ``wait``.\n\n return array.reduce(function (done, value) {\n return Q.wait(done, doWork(value));\n });\n\n\n## Recovery\n\nYou can use the rejection callback of ``when`` blocks to\nrecover from failure. Supposing that ``doIt`` will\nintermittently fail (perhaps because of network conditions),\n``justDoIt`` will just keep trying indifinitely.\n\n function justDoIt(value) {\n var work = doIt(value);\n work = timeout(1000, work);\n return Q.when(work, function (work) {\n return work;\n }, function errback(reason) {\n // just do it again\n return justDoIt(value);\n });\n }\n\nThis will not blow out the stack because ``when`` blocks\nguarantee that the fulfillment and rejection callbacks will\nonly be called on their own turn of the event loop.\n\n\n## Conditional Array Serial Join\n\nConsider the process of looking for the first directory in\nan array of paths that contains a particular file. To do\nthis with a synchronous file API is very straight-forward.\n\n function find(basePaths, soughtPath) {\n for (var i = 0, ii = basePaths.length; i < ii; i++) {\n var consideredPath = FS.join(basePaths[i], soughtPath);\n if (FS.isFile(consideredPath))\n return consideredPath;\n }\n throw new Error(\"Can't find.\");\n }\n\nTo do this with an asynchronous ``FS.isFile`` is more\nelaborate. It is a serial iteration, but it halts at the\nfirst success. This can be accomplished by creating a chain\nof functions, each making progress on the returned promise\nuntil the matching path is found, otherwise returning the\nvalue returned by the next function in line, until all\noptions are exhausted and returning a rejection.\n\n function find(basePaths, soughtPath) {\n var find = basePaths.reduceRight(function (otherwise, basePath) {\n return function () {\n var consideredPath = FS.join(basePath, soughtPath);\n var isFile = FS.isFile(consideredPath);\n return Q.when(isFile, function (isFile) {\n if (isFile) {\n return consideredPath;\n } else {\n return otherwise();\n }\n });\n };\n }, function otherwise() {\n throw new Error(\"Can't find\");\n });\n return find();\n }\n\n\nTHE HALLOWED API\n----------------\n\n\n## ``when(value, fulfilled_opt, rejected_opt)``\n\nArranges for ``fulfilled`` to be called:\n\n- with the value as its sole argument\n- in a future turn of the event loop\n- if and when the value is or becomes a fully resolved\n\nArranges for ``rejected`` to be called:\n\n- with a value respresenting the reason why the object will\n never be resolved, typically an ``Error`` object.\n- in a future turn of the event loop\n- if the value is a promise and\n - if and when the promise is rejected\n\nReturns a promise:\n\n- that will resolve to the value returned by either of the\n callbacks, if either of those functions are called, or\n- that will be rejected if the value is rejected and no\n ``rejected`` callback is provided, thus forwarding\n rejections by default.\n\nThe value may be truly __any__ value. It can be a function.\nIt can be a promise.\n\nEither callback may be falsy, in which case it will not be\ncalled.\n\nGuarantees:\n\n- ``fulfilled`` will not be called before when returns.\n- ``rejected`` will not be called before when returns.\n- ``fulfilled`` will not be called more than once.\n- ``rejected`` will not be called more than once.\n- If ``fulfilled`` is called, ``rejected`` will never be called.\n- If ``rejected`` is called, ``fulfilled`` will never be called.\n- If a promise is never resolved, neither callback will\n ever be called.\n\nTHIS IS COOL\n\n- You can set up an entire chain of causes and effects in the\n duration of a single event and be guaranteed that any invariants\n in your lexical scope will not...vary.\n- You can both receive a promise from a sketchy API and return a\n promise to some other sketchy API and, as long as you trust this\n module, all of these guarantees are still provided.\n- You can use when to compose promises in a variety of ways, for\n example:\n\nINTERSECTION\n\n function and(a, b) {\n return Q.when(a, function (a) {\n return Q.when(b, function (b) {\n // ...\n });\n })\n }\n\n\n## ``defer()``\n\nReturns a \"deferred\" object with a:\n\n- ``promise`` property\n- ``resolve(value)`` function\n- ``reject(reason)`` function\n\nThe promise is suitable for passing as a value to the\n``when`` function, among others.\n\nCalling resolve with a promise notifies all observers that\nthey must now wait for that promise to resolve.\n\nCalling resolve with a rejected promise notifies all\nobservers that the promise will never be fully resolved with\nthe rejection reason. This forwards through the the chain\nof ``when`` calls and their returned promises until it\nreaches a ``when`` call that has a ``rejected`` callback.\n\nCalling resolve with a fully resolved value notifies all\nobservers that they may proceed with that value in a future\nturn. This forwards through the ``fulfilled`` chain of any\npending ``when`` calls.\n\nCalling ``reject`` with a reason is equivalent to resolving\nwith a rejection.\n\nIn all cases where the resolution of a promise is set,\n(promise, rejection, value) the resolution is permanent and\ncannot be reset. All future observers of the resolution of\nthe promise will be notified of the resolved value, so it is\nsafe to call ``when`` on a promise regardless of whether it\nhas been or will be resolved.\n\n\nTHIS IS COOL\n\nThe Deferred separates the promise part from the resolver\npart. So:\n\n- You can give the promise to any number of consumers and\n all of them will observe the resolution independently.\n Because the capability of observing a promise is\n separated from the capability of resolving the promise,\n none of the recipients of the promise have the ability\n to \"trick\" other recipients with misinformation.\n\n- You can give the resolver to any number of producers and\n whoever resolves the promise first wins. Furthermore,\n none of the producers can observe that they lost unless\n you give them the promise part too.\n\n\nUNION\n\n function or(a, b) {\n var union = Q.defer();\n Q.when(a, union.resolve);\n Q.when(b, union.resolve);\n return union.promise;\n }\n\n\n## ``ref(value)``\n\nIf value is a promise, returns the promise.\n\nIf value is not a promise, returns a promise that has\nalready been resolved with the given value.\n\n\n## ``def(value)``\n\nAnnotates a value, wrapping it in a promise, such that that\nit is a local promise object which cannot be serialized and\nsent to resolve a remote promise.\n\nA def'ed value will respond to the ``\"isDef\"`` message\nwithout a rejection so remote promise communication\nlibraries can distinguish it from non-def values.\n\n\n## ``reject(reason)``\n\nReturns a promise that has already been rejected with the\ngiven reason.\n\nThis is useful for conditionally forwarding a rejection\nthrough an errback.\n\n Q.when(API.getPromise(), function (value) {\n return doSomething(value);\n }, function (reason) {\n if (API.stillPossible()) {\n return API.tryAgain();\n } else {\n return Q.reject(reason);\n }\n })\n\nUnconditionally forwarding a rejection is equivalent to\nomitting an errback on a when call.\n\n Q.when(API.getPromise(), function (value) {\n return doSomething(value);\n }, function (reason) {\n return Q.reject(reason);\n })\n\nSimplifies to:\n\n Q.when(API.getPromise(), function (value) {\n return doSomething(value);\n })\n\n\n## ``isPromise(value)``\n\nReturns whether the given value is a promise.\n\n\n## ``isResolved(value)``\n\nReturns whether the given value is fully resolved. The\ngiven value may be any value, including but not limited to\npromises returned by ``defer`` and ``ref``. Rejected\npromises are not considered resolved.\n\n\n## ``isRejected(value)``\n\nReturns whether the given value is a rejected promise.\n\n\n## ``end(promise)``\n\nAccepts a promise that is intended to be the last promise in\na chain of promises. If an error propagates to the end of\nthe promise chain, it will be thrown as an exception and\nhandled by either NodeJS or the browser as an uncaught\nexception.\n\n\n## ``enqueue(callback Function)``\n\nCalls ``callback`` in a future turn.\n\n\nADVANCED API\n------------\n\nThe ``ref`` promise constructor establishes the basic API\nfor performing operations on objects: \"get\", \"put\", \"del\",\n\"post\", \"apply\", and \"keys\". This set of \"operators\" can be\nextended by creating promises that respond to messages with\nother operator names, and by sending corresponding messages\nto those promises.\n\n\n## ``makePromise(handlers, fallback_opt, valueOf_opt)``\n\nCreates a stand-alone promise that responds to messages.\nThese messages have an operator like \"when\", \"get\", \"put\",\nand \"post\", corresponding to each of the above functions for\nsending messages to promises.\n\nThe ``handlers`` are an object with function properties\ncorresponding to operators. When the made promise receives\na message and a corresponding operator exists in the\n``handlers``, the function gets called with the variadic\narguments sent to the promise. If no ``handlers`` object\nexists, the ``fallback`` function is called with the operator,\nand the subsequent variadic arguments instead. These\nfunctions return a promise for the eventual resolution of\nthe promise returned by the message-sender. The default\nfallback returns a rejection.\n\nThe ``valueOf`` function, if provided, overrides the\n``valueOf`` function of the returned promise. This is useful\nfor providing information about the promise in the same turn\nof the event loop. For example, resolved promises return\ntheir resolution value and rejections return an object that\nis recognized by ``isRejected``.\n\n\n## ``send(value, operator, ...args)``\n\nSends an arbitrary message to a promise.\n\nCare should be taken not to introduce control-flow hazards\nand security holes when forwarding messages to promises.\nThe functions above, particularly ``when``, are carefully\ncrafted to prevent a poorly crafted or malicious promise\nfrom breaking the invariants like not applying callbacks\nmultiple times or in the same turn of the event loop.\n\n\n## ``get(object, name)``\n\nReturns a promise for the named property of an object,\nalbeit a promise for an object.\n\n\n## ``put(object, name, value)``\n\nReturns a promise to set the named property of an object,\nalbeit a promise, to the given value.\n\n\n## ``del(object, name)``\n\nReturns a promise to delete the named property of an object,\nalbeit a promise.\n\n\n## ``post(object, name, arguments)``\n\nReturns a promise to call the named function property of an\neventually fulfilled object with the given array of\narguments. The object itself is ``this`` in the function.\n\n\n## ``invoke(object, name, ...arguments)``\n\nReturns a promise to call the named function property of an\neventually fulfilled object with the given variadic\narguments. The object itself is ``this`` in the function.\n\n\n## ``keys(object)``\n\nReturns a promise for an array of the property names of the\neventually fulfilled object.\n\n\n## ``apply(function, this, arguments)``\n\nReturns a promise for the result of calling an eventually\nfulfilled function, with the given values for the ``this``\nand ``arguments`` array in that function.\n\n\n## ``call(function, this, ...arguments)``\n\nReturns a promise for the result of eventually calling the\nfulfilled function, with the given context and variadic\narguments.\n\n\n## ``all([...promises])``\n\nReturns a promise for an array of the fulfillment of each\nrespective promise, or rejects when the first promise is\nrejected.\n\n\n## ``wait(...objects)``\n\nReturns a promise for the fulfilled value of the first\nobject when all of the objects have been fulfilled, or the\nrejection of the first object to be rejected from left to\nright.\n\n\n## ``join(...objects, callback(...objects))``\n\nReturns a promise for the value eventually fulfilled by the\nreturn value of the callback, or the rejection of the first\nobject to be rejected from left to right. If and when all\nof the variadic object arguments have been fulfilled, the\ncallback is called with the respective fulfillment values\nvariadically.\n\n\n## ``fin(promise, callback())``\n\nLike a ``finally`` clause, allows you to observe either the\nfulfillment or rejection of a callback, but to do so without\nmodifying the final value. This is useful for collecting\nresources regardless of whether a job succeeded, like\nclosing a database connection, shutting a server down, or\ndeleting an unneeded key from an object. The callback \nreceives no arguments.\n\n\n## ``end(promise)``\n\nAccepts a promise and returns ``undefined``, to terminate a\nchain of promises at the end of a program. If the promise\nis rejected, throws it as an exception in a future turn of\nthe event loop.\n\nSince exceptions thrown in ``when`` callbacks are consumed\nand transformed into rejections, exceptions are easy to\naccidentally silently ignore. It is furthermore non-trivial\nto get those exceptions reported since the obvious way to do\nthis is to use ``when`` to register a rejection callback,\nwhere ``throw`` would just get consumed again. ``end``\narranges for the error to be thrown in a future turn of the\nevent loop, so it won't be caught; it will cause the\nexception to emit a browser's ``onerror`` event or NodeJS's\n``process`` ``\"uncaughtException\"``.\n\n\n## ``async(generatorFunction)``\n\nThis is an experimental tool for converting a generator\nfunction into a deferred function. This has the potential\nof reducing nested callbacks in engines that support\n``yield``. See ``examples/async-generators/README.md`` for\nfurther information.\n\n\nChaining\n--------\n\nPromises created by the Q API support chaining for some\nfunctions. The ``this`` promise becomes the first argument\nof the corresponding Q API function. For example, the\nfollowing are equivalent:\n\n- ``when(promise, fulfilled)`` and\n ``promise.then(fulfilled)``.\n- ``end(promise)`` and ``promise.end()``.\n\nThe following functions are supported for chaining:\n\n- ``.when`` (``.then``)\n- ``.get``\n- ``.put``\n- ``.del``\n- ``.post``\n- ``.invoke``\n- ``.apply``\n- ``.call``\n- ``.keys``\n- ``.all``\n- ``.wait`` (``.all().get(0)``)\n- ``.join`` (``.all().when(function ([...]) {}))``)\n- ``.fin``\n- ``.end``\n\n\nCopyright 2009-2011 Kristopher Michael Kowal\nMIT License (enclosed)\n\n",
"readmeFilename": "README.md",
"_id": "q@0.7.2",
"_from": "q@0.7.2"
}