Skip to content

Instantly share code, notes, and snippets.

@benmoss
Created August 7, 2014 15:30
Show Gist options
  • Save benmoss/493249af315811daad9f to your computer and use it in GitHub Desktop.
Save benmoss/493249af315811daad9f to your computer and use it in GitHub Desktop.
{
"name": "rsvp",
"namespace": "RSVP",
"version": "3.0.11",
"description": "A lightweight library that provides tools for organizing asynchronous code",
"main": "dist/rsvp.js",
"directories": {
"lib": "lib"
},
"devDependencies": {
"brfs": "0.0.8",
"broccoli-closure-compiler": "^0.2.0",
"broccoli-compile-modules": "git://github.com/eventualbuddha/broccoli-compile-modules",
"broccoli-concat": "0.0.7",
"broccoli-file-mover": "^0.4.0",
"broccoli-jshint": "^0.5.1",
"broccoli-merge-trees": "^0.1.4",
"broccoli-static-compiler": "^0.1.4",
"broccoli-string-replace": "0.0.1",
"browserify": "^4.2.0",
"ember-cli": "0.0.40",
"ember-publisher": "0.0.6",
"es6-module-transpiler-amd-formatter": "0.0.1",
"express": "^4.5.0",
"jshint": "~0.9.1",
"mkdirp": "^0.5.0",
"mocha": "^1.20.1",
"promises-aplus-tests": "git://github.com/stefanpenner/promises-tests.git",
"testem": "^0.6.17"
},
"scripts": {
"test": "testem ci",
"test-server": "testem",
"lint": "jshint lib",
"prepublish": "ember build --environment production",
"aplus": "browserify test/main.js",
"build-all": "ember build --environment production && browserify ./test/main.js -o tmp/test-bundle.js"
},
"repository": {
"type": "git",
"url": "https://github.com/tildeio/rsvp.js.git",
"dist": "git@github.com:components/rsvp.js.git"
},
"bugs": {
"url": "https://github.com/tildeio/rsvp.js/issues"
},
"keywords": [
"promises",
"futures"
],
"author": {
"name": "Tilde, Inc. & Stefan Penner"
},
"license": "MIT",
"readme": "# RSVP.js [![Build Status](https://secure.travis-ci.org/tildeio/rsvp.js.png?branch=master)](http://travis-ci.org/tildeio/rsvp.js)\n\nRSVP.js provides simple tools for organizing asynchronous code.\n\nSpecifically, it is a tiny implementation of Promises/A+.\n\nIt works in node and the browser.\n\n## downloads\n\n- [rsvp-latest](http://rsvpjs-builds.s3.amazonaws.com/rsvp-latest.js)\n- [rsvp-latest (minified)](http://rsvpjs-builds.s3.amazonaws.com/rsvp-latest.min.js)\n\n## Promises\n\n\nAlthough RSVP is es6 compliant, it does bring along some extra toys. If you would prefer a strict es6 subset, I would suggest checking out our sibling project https://github.com/jakearchibald/es6-promise, It is RSVP but stripped down to the es6 spec features.\n\n## Bower\n\n`bower install -S rsvp`\n\n## NPM\n\n`npm install --save rsvp`\n\n`RSVP.Promise` is an implementation of\n[Promises/A+](http://promises-aplus.github.com/promises-spec/) that passes the\n[test suite](https://github.com/promises-aplus/promises-tests).\n\nIt delivers all promises asynchronously, even if the value is already\navailable, to help you write consistent code that doesn't change if the\nunderlying data provider changes from synchronous to asynchronous.\n\nIt is compatible with [TaskJS](http://taskjs.org/), a library by Dave\nHerman of Mozilla that uses ES6 generators to allow you to write\nsynchronous code with promises. It currently works in Firefox, and will\nwork in any browser that adds support for ES6 generators. See the\nsection below on TaskJS for more information.\n\n### Basic Usage\n\n```javascript\nvar RSVP = require('rsvp');\n\nvar promise = new RSVP.Promise(function(resolve, reject) {\n // succeed\n resolve(value);\n // or reject\n reject(error);\n});\n\npromise.then(function(value) {\n // success\n}, function(value) {\n // failure\n});\n```\n\nOnce a promise has been resolved or rejected, it cannot be resolved or\nrejected again.\n\nHere is an example of a simple XHR2 wrapper written using RSVP.js:\n\n```javascript\nvar getJSON = function(url) {\n var promise = new RSVP.Promise(function(resolve, reject){\n var client = new XMLHttpRequest();\n client.open(\"GET\", url);\n client.onreadystatechange = handler;\n client.responseType = \"json\";\n client.setRequestHeader(\"Accept\", \"application/json\");\n client.send();\n\n function handler() {\n if (this.readyState === this.DONE) {\n if (this.status === 200) { resolve(this.response); }\n else { reject(this); }\n }\n };\n });\n\n return promise;\n};\n\ngetJSON(\"/posts.json\").then(function(json) {\n // continue\n}, function(error) {\n // handle errors\n});\n```\n\n### Chaining\n\nOne of the really awesome features of Promises/A+ promises are that they\ncan be chained together. In other words, the return value of the first\nresolve handler will be passed to the second resolve handler.\n\nIf you return a regular value, it will be passed, as is, to the next\nhandler.\n\n```javascript\ngetJSON(\"/posts.json\").then(function(json) {\n return json.post;\n}).then(function(post) {\n // proceed\n});\n```\n\nThe really awesome part comes when you return a promise from the first\nhandler:\n\n```javascript\ngetJSON(\"/post/1.json\").then(function(post) {\n // save off post\n return getJSON(post.commentURL);\n}).then(function(comments) {\n // proceed with access to posts and comments\n});\n```\n\nThis allows you to flatten out nested callbacks, and is the main feature\nof promises that prevents \"rightward drift\" in programs with a lot of\nasynchronous code.\n\nErrors also propagate:\n\n```javascript\ngetJSON(\"/posts.json\").then(function(posts) {\n\n}).catch(function(error) {\n // since no rejection handler was passed to the\n // first `.then`, the error propagates.\n});\n```\n\nYou can use this to emulate `try/catch` logic in synchronous code.\nSimply chain as many resolve callbacks as a you want, and add a failure\nhandler at the end to catch errors.\n\n```javascript\ngetJSON(\"/post/1.json\").then(function(post) {\n return getJSON(post.commentURL);\n}).then(function(comments) {\n // proceed with access to posts and comments\n}).catch(function(error) {\n // handle errors in either of the two requests\n});\n```\n\nYou can also use `catch` for error handling, which is a shortcut for\n`then(null, rejection)`, like so:\n\n```javascript\ngetJSON(\"/post/1.json\").then(function(post) {\n return getJSON(post.commentURL);\n}).catch(function(error) {\n // handle errors\n});\n```\n\n## Error Handling\n\nThere are times when dealing with promises that it seems like any errors\nare being 'swallowed', and not properly raised. This makes is extremely\ndifficult to track down where a given issue is coming from. Thankfully,\n`RSVP` has a solution for this problem built in.\n\nYou can register functions to be called when an uncaught error occurs\nwithin your promises. These callback functions can be anything, but a common\npractice is to call `console.assert` to dump the error to the console.\n\n```javascript\nRSVP.on('error', function(reason) {\n console.assert(false, reason);\n});\n```\n\n**NOTE:** promises do allow for errors to be handled asynchronously, so\nthis callback may result in false positives.\n\n**NOTE:** Usage of `RSVP.configure('onerror', yourCustomFunction);` is\ndeprecated in favor of using `RSVP.on`.\n\n## Arrays of promises\n\nSometimes you might want to work with many promises at once. If you\npass an array of promises to the `all()` method it will return a new\npromise that will be fulfilled when all of the promises in the array\nhave been fulfilled; or rejected immediately if any promise in the array\nis rejected.\n\n```javascript\nvar promises = [2, 3, 5, 7, 11, 13].map(function(id){\n return getJSON(\"/post/\" + id + \".json\");\n});\n\nRSVP.all(promises).then(function(posts) {\n // posts contains an array of results for the given promises\n}).catch(function(reason){\n // if any of the promises fails.\n});\n```\n\n## Hash of promises\n\nIf you need to reference many promises at once (like `all()`), but would like\nto avoid encoding the actual promise order you can use `hash()`. If you pass\nan object literal (where the values are promises) to the `hash()` method it will\nreturn a new promise that will be fulfilled when all of the promises have been\nfulfilled; or rejected immediately if any promise is rejected.\n\nThe key difference to the `all()` function is that both the fulfillment value\nand the argument to the `hash()` function are object literals. This allows\nyou to simply reference the results directly off the returned object without\nhaving to remember the initial order like you would with `all()`.\n\n```javascript\nvar promises = {\n posts: getJSON(\"/posts.json\"),\n users: getJSON(\"/users.json\")\n};\n\nRSVP.hash(promises).then(function(results) {\n console.log(results.users) // print the users.json results\n console.log(results.posts) // print the posts.json results\n});\n```\n\n## All settled and hash settled\n\nSometimes you want to work with several promises at once, but instead of\nrejecting immediately if any promise is rejected, as with `all()` or `hash()`,\nyou want to be able to inspect the results of all your promises, whether\nthey fulfill or reject. For this purpose, you can use `allSettled()` and\n`hashSettled()`. These work exactly like `all()` and `hash()`, except that\nthey fulfill with an array or hash (respectively) of the constituent promises'\nresult states. Each state object will either indicate fulfillment or\nrejection, and provide the corresponding value or reason. The states will take\none of the following formats:\n\n```javascript\n{ state: 'fulfilled', value: value }\n or\n{ state: 'rejected', reason: reason }\n```\n\n## Deferred\n\n> The `RSVP.Promise` constructor is generally a better, less error-prone choice\n> than `RSVP.defer()`. Promises are recommended unless the specific \n> properties of deferred are needed.\n\nSometimes one need to create a deferred object, without immediately specifying\nhow it will be resolved. These deferred objects are essentially a wrapper around\na promise, whilst providing late access to the `resolve()` and `reject()` methods.\n\nA deferred object has this form: `{ promise, resolve(x), reject(r) }`.\n\n```javascript\nvar deferred = RSVP.defer();\n// ...\ndeferred.promise // access the promise\n// ...\ndeferred.resolve();\n\n```\n\n## TaskJS\n\nThe [TaskJS](http://taskjs.org/) library makes it possible to take\npromises-oriented code and make it synchronous using ES6 generators.\n\nLet's review an earlier example:\n\n```javascript\ngetJSON(\"/post/1.json\").then(function(post) {\n return getJSON(post.commentURL);\n}).then(function(comments) {\n // proceed with access to posts and comments\n}).catch(function(reason) {\n // handle errors in either of the two requests\n});\n```\n\nWithout any changes to the implementation of `getJSON`, you could write\nthe following code with TaskJS:\n\n```javascript\nspawn(function *() {\n try {\n var post = yield getJSON(\"/post/1.json\");\n var comments = yield getJSON(post.commentURL);\n } catch(error) {\n // handle errors\n }\n});\n```\n\nIn the above example, `function *` is new syntax in ES6 for\n[generators](http://wiki.ecmascript.org/doku.php?id=harmony:generators).\nInside a generator, `yield` pauses the generator, returning control to\nthe function that invoked the generator. In this case, the invoker is a\nspecial function that understands the semantics of Promises/A, and will\nautomatically resume the generator as soon as the promise is resolved.\n\nThe cool thing here is the same promises that work with current\nJavaScript using `.then` will work seamlessly with TaskJS once a browser\nhas implemented it!\n\n## Instrumentation\n\n```js\nfunction listener (event) {\n event.guid // guid of promise. Must be globally unique, not just within the implementation\n event.childGuid // child of child promise (for chained via `then`)\n event.eventName // one of ['created', 'chained', 'fulfilled', 'rejected']\n event.detail // fulfillment value or rejection reason, if applicable\n event.label // label passed to promise's constructor\n event.timeStamp // milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now\n}\n\nRSVP.configure('instrument', true | false);\nRSVP.on('created', listener);\nRSVP.on('chained', listener);\nRSVP.on('fulfilled', listener);\nRSVP.on('rejected', listener);\n```\n\nEvents are only triggered when `RSVP.configure('instrument')` is true, although\nlisteners can be registered at any time.\n\n## Building & Testing\n\nCustom tasks:\n\n* `ember build` - Build distribution\n* `testem ci` - Run tests.\n* `testem` - Run test server.\n",
"readmeFilename": "README.md",
"homepage": "https://github.com/tildeio/rsvp.js",
"_id": "rsvp@3.0.11",
"_shasum": "e1ba949812367ca0688ef61aec3f68eb567a27ed",
"_from": "rsvp@>=3.0.9-0 <4.0.0-0",
"_resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.0.11.tgz"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment