{"id":18645443,"url":"https://github.com/cscott/prfun","last_synced_at":"2025-08-20T04:32:30.698Z","repository":{"id":14018582,"uuid":"16720385","full_name":"cscott/prfun","owner":"cscott","description":"Helper functions for ES6 promises","archived":false,"fork":false,"pushed_at":"2019-10-05T03:05:15.000Z","size":177,"stargazers_count":64,"open_issues_count":1,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-09T00:12:49.419Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cscott.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-11T05:19:07.000Z","updated_at":"2023-09-08T16:45:26.000Z","dependencies_parsed_at":"2022-08-25T17:52:15.019Z","dependency_job_id":null,"html_url":"https://github.com/cscott/prfun","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Fprfun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Fprfun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Fprfun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Fprfun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cscott","download_url":"https://codeload.github.com/cscott/prfun/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230394228,"owners_count":18218707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T06:15:54.271Z","updated_at":"2024-12-19T07:06:35.556Z","avatar_url":"https://github.com/cscott.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# prfun\n[![NPM][NPM1]][NPM2]\n\n[![Build Status][1]][2] [![dependency status][3]][4] [![dev dependency status][5]][6]\n\nHelper functions for ES6 Promises.\n\nThe `Promise` implementation included in the [ES6] \"harmony\" Javascript\nspecification is missing some of the useful utility functions that\nare common in popular packages like [bluebird], [when], and [q].\n\nThis package supplies them.  It optionally loads a `Promise`\nimplementation from [core-js], if there is not already a `Promise`\nimplementation present.  The `prfun` package also requires an\nimplementation of `Object.setPrototypeOf`; it will attempt to\nload this from [core-js] if not already present.   Implementations\nloaded from [core-js] do not pollute the global namespace.\n\nPortions of the API and test suite are borrowed from [bluebird], [when],\nand [q].\n\n## Usage\n\nUnlike many other utility packages for `Promise`, `prfun` does not\npollute the global namespace.  By default `prfun` creates a `Promise`\nsubclass, using ES6 semantics.  This means you use it like:\n```\nvar Promise = require('prfun'); // subclasses global.Promise\n// note that global.Promise !== Promise after this point\n```\nor\n```\nvar SomeOtherPromise = require( /*something*/ );\nvar Promise = require('prfun/wrap')( SomeOtherPromise );\n// Note that the same `Promise` object will always be\n// returned if given the same `SomeOtherPromise` to wrap.\n```\nNote that the `SomeOtherPromise` implementation must support `Promise`\nsubclassing using ES6 semantics.  (The implementations in [babybird],\n[es6-shim], and [core-js] are known to do so.)  We will call the subclass\ncreated by `prfun` a \"`prfun` `Promise`\".\n\nAccording to the ES6 `Promise` spec, all `Promise` methods (including\nthe new ones added by `prfun`) will return an instance of the subclass\nwhen invoked on an instance of the subclass.  That is, if you are given\na `prfun` `Promise` and you call `then` on it, the result will be\nanother `prfun` `Promise`.  So within your own code you can assume\nthat all `prfun` helper methods will be present, and they will all\nreturn `prfun` `Promise`s which also contain all the `prfun` helper\nmethods.\n\nIf your code is given a promise from an outside API, and you can't\nguarantee that it is a `prfun` Promise, then you can use\n`Promise.resolve` in order to cast the outside promise to a `prfun`\n`Promise`.   For example:\n```\nvar Promise = require('prfun'); // this is a \"prfun Promise\"\n\nfunction myApi(externalPromise) {\n  return Promise.resolve(externalPromise).tap(function(value) {\n    // we can call 'tap' after resolving the external promise\n  }); // this result will also be a \"prfun Promise\"\n}\n```\n\nIn order to *modify the global `Promise` object* (instead of\nsubclassing), use:\n```\nrequire('prfun/smash');\n// global.Promise.reduce, global.Promise.tap, etc, now exist.\n```\nThis is how `prfun` worked by default prior to version 2.0, but it\nit not recommended: stomping on global objects is never a good idea,\nand future changes to the `Promise` object in ES7 or incompatible\nmethods added by your third-party `Promise` implementation or other\nlibraries could break your code in mysterious ways.\n\n## API\n\n- [Collections](#collections)\n    - [`Promise.all`]\n    - [`Promise#all`]\n    - [`Promise.filter`]\n    - [`Promise#filter`]\n    - [`Promise.join`]\n    - [`Promise.map`]\n    - [`Promise#map`]\n    - [`Promise.props`]\n    - [`Promise#props`]\n    - [`Promise.race`]\n    - [`Promise#race`]\n    - [`Promise.reduce`]\n    - [`Promise#reduce`]\n    - [`Promise.reduceRight`]\n    - [`Promise#reduceRight`]\n    - [`Promise#spread`]\n- [Utility](#utility)\n    - [`Promise.bind`]\n    - [`Promise#bind`]\n    - [`Promise#call`]\n    - [`Promise#get`]\n    - [`Promise#return`]\n    - [`Promise#tap`]\n    - [`Promise#then0`]\n    - [`Promise#throw`]\n    - [`Promise.defer`]\n    - [`Promise#done`]\n- [Try/caught/finally](#trycaughtfinally)\n    - [`Promise.try`]\n    - [`Promise#caught`]\n    - [`Promise#finally`]\n- [Method wrappers and helpers](#method-wrappers-and-helpers)\n    - [`Promise.guard`]\n    - [`Promise.method`]\n    - [`Promise#nodify`]\n    - [`Promise.promisify`]\n- [Timers](#timers)\n    - [`Promise.delay`]\n    - [`Promise#delay`]\n    - [`Promise#timeout`]\n- [Generators](#generators)\n    - [`Promise.async`]\n\n### Collections\n\nMethods of `Promise` instances and core static methods of the Promise\nclass to deal with collections of promises or mixed promises and\nvalues.\n\n#### `Promise.all(Array\u003cdynamic\u003e|Iterable values)` → `Promise`\n[`Promise.all`]: #promiseallarraydynamiciterable-values--promise\n\nThis is an\n[ES6 built-in](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise.all).\nNote that, unlike many libraries, the ES6\nmethod accepts as its argument only an array (or iterable), not a\npromise for an array (or iterable).  Also, the ES6 method does not\npreserve sparsity in the passed array.\n\nGiven an array or iterable which contains promises (or a mix of\npromises and values) return a promise that is fulfilled when all the\nitems in the array are fulfilled. The promise's fulfillment value is\nan array with fulfillment values at respective positions to the\noriginal iterable. If any promise in the iterable rejects, the\nreturned promise is rejected with the rejection reason.\n\n\u003chr\u003e\n\n#### `Promise#all()` → `Promise`\n[`Promise#all`]: #promiseall--promise\n\nConvenience method for:\n```js\npromise.then(function(value) {\n    return Promise.all(value);\n});\n```\n\nSee [`Promise.all`].\n\u003chr\u003e\n\n#### `Promise.filter(Array\u003cdynamic\u003e|Promise values, Function callback [, Object thisArg])` → `Promise`\n[`Promise.filter`]: #promisefilterarraydynamicpromise-values-function-callback--object-thisarg--promise\n\nFilters an array-like, or a promise of an array-like, using the provided\n`callback` function.\n\nConvenience method for:\n```js\nPromise.resolve(values).filter(callback, thisArg);\n```\n\nSee [`Promise#filter`].\n\u003chr\u003e\n\n#### `Promise#filter(Function callback [, Object thisArg])` → `Promise`\n[`Promise#filter`]: #promisefilterfunction-callback--object-thisarg--promise\n\nCall the given `callback` function once for each element in (a promise of)\nan array which contains a promises (or a mix of promises and values), and\nconstruct a new array of all the values for which the callback returns\n(a promise of) a true value.  The `callback` function has\nthe signature `(item, index, array)` where `item` is the resolved\nvalue of the promise in the input array at `index`. If any promise in\nthe input array is rejected the returned promise is rejected as well.\n\nIf a `thisArg` parameter is provided, it will be passed to `callback`\nwhen invoked, for use as its `this` value.  Otherwise, the value\n`undefined` will be passed for use as its `this` value.\n\nNote that the callback is invoked on each element in the array as soon\nas possible; that is, as soon as the promise for each element is\nresolved the callback is invoked for that element, without waiting for\nother elements to be resolved.\n\nThe behavior of `filter` matches\n[`Array.prototype.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)\nas much as possible.  Note that this means that non-array objects are often\naccepted without error, and any object without a length field returns a\nzero-length array.  For example,\n`Array.prototype.filter.call(123, Object.toString)` returns `[]`.\n`Promise#filter` rejects with a `TypeError` if `Array.prototype.filter`\nwould throw a `TypeError`.\n\n*The original array is not modified.*\n\n\u003chr\u003e\n\n#### `Promise.join([dynamic value...])` → `Promise`\n[`Promise.join`]: #promisejoindynamic-value--promise\n\nLike [`Promise.all`] but instead of having to pass an array, the array\nis generated from the passed variadic arguments.\n\nSo instead of:\n\n```js\nPromise.all([a, b]).spread(function(aResult, bResult) {\n\n});\n```\n\nYou can do:\n\n```js\nPromise.join(a, b).spread(function(aResult, bResult) {\n\n});\n```\n\n\u003chr\u003e\n\n#### `Promise.map(Array\u003cdynamic\u003e|Promise values, Function mapper [, Object thisArg])` → `Promise`\n[`Promise.map`]: #promisemaparraydynamicpromise-values-function-mapper--object-thisarg--promise\n\nMaps an array-like, or a promise of an array-like, using the provided\n`mapper` function.\n\nConvenience method for:\n```js\nPromise.resolve(values).map(mapper, thisArg);\n```\n\nSee [`Promise#map`].\n\u003chr\u003e\n\n#### `Promise#map(Function mapper [, Object thisArg])` → `Promise`\n[`Promise#map`]: #promisemapfunction-mapper--object-thisarg--promise\n\nMap (a promise of) an array which contains a promises (or\na mix of promises and values) with the given `mapper` function with\nthe signature `(item, index, array)` where `item` is the resolved\nvalue of a respective promise in the input array. If any promise in\nthe input array is rejected the returned promise is rejected as well.\n\nIf the `mapper` function returns promises or thenables, the returned\npromise will wait for all the mapped results to be resolved as well,\nas if [`Promise.all`] were invoked on the result.\n\nIf a `thisArg` parameter is provided, it will be passed to `mapper`\nwhen invoked, for use as its `this` value.  Otherwise, the value\n`undefined` will be passed for use as its `this` value.\n\nNote that the `mapper` function is invoked on each element in the\narray as soon as possible; that is, as soon as the promise for each\nelement is resolved `mapper` is invoked for that element, without\nwaiting for other elements to be resolved.\n\nThe behavior of `map` matches\n[`Array.prototype.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)\nas much as possible.  Note that this means that non-array objects are often\naccepted without error, and any object without a length field returns a\nzero-length array.  For example,\n`Array.prototype.map.call(123, Object.toString)` returns `[]`.\n`Promise#map` rejects with a `TypeError` if `Array.prototype.map`\nwould throw a `TypeError`.\n\n*The original array is not modified.*\n\n\u003chr\u003e\n\n#### `Promise.props(Object|Promise object)` → `Promise`\n[`Promise.props`]: #promisepropsobjectpromise-object--promise\n\nLike [`Promise.all`] but for object properties instead of array\nitems. Returns a promise that is fulfilled when all the properties of\nthe object are fulfilled. The promise's fulfillment value is an object\nwith fulfillment values at respective keys to the original object. If\nany promise in the object rejects, the returned promise is rejected\nwith the rejection reason.\n\nIf `object` is a `Promise` or \"thenable\" --- that is, if it has a\nproperty named `then` which is a callable function --- then it will be\ntreated as a promise for the object, rather than for its properties.\nAll other objects are treated for their own enumerable properties, as returned by\n[`Object.keys`].\n\n```js\nPromise.props({\n    pictures: getPictures(),\n    comments: getComments(),\n    tweets: getTweets()\n}).then(function(result){\n    console.log(result.tweets, result.pictures, result.comments);\n});\n```\n\nNote that if you have no use for the result object other than\nretrieving the properties, it is more convenient to use\n[`Promise.all`] and [`Promise#spread`]:\n\n```js\nPromise.all([getPictures(), getComments(), getTweets()])\n.spread(function(pictures, comments, tweets) {\n    console.log(pictures, comments, tweets);\n});\n```\n\n*The original object is not modified.*\n\n[`Object.keys`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys\n\n\u003chr\u003e\n\n#### `Promise#props()` → `Promise`\n[`Promise#props`]: #promiseprops--promise\n\nConvenience method for:\n```js\npromise.then(function(value) {\n    return Promise.props(value);\n});\n```\n\nSee [`Promise.props`].\n\u003chr\u003e\n\n#### `Promise.race(Array\u003cdynamic\u003e|Iterable values)` → `Promise`\n[`Promise.race`]: #promiseracearraydynamiciterable-values--promise\n\nThis is an\n[ES6 built-in](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise.race).\nNote that, unlike many libraries, the ES6\nmethod accepts as its argument only an array (or iterable), not a\npromise for an array (or iterable).  The ES6 method also returns\n**a promise that never resolves** if you promise a zero-length array;\nuser beware!\n\nGiven an array or iterable which contains promises (or a mix of\npromises and values) return a promise that is fulfilled or rejected as\nsoon as a promise in the array is fulfilled or rejected with the\nrespective rejection reason or fulfillment value.\n\n\u003chr\u003e\n\n#### `Promise#race()` → `Promise`\n[`Promise#race`]: #promiserace--promise\n\nConvenience method for:\n```js\npromise.then(function(value) {\n    return Promise.race(value);\n});\n```\n\nSee [`Promise.race`].\n\u003chr\u003e\n\n#### `Promise.reduce(Array\u003cdynamic\u003e|Promise values, Function reducer [, dynamic initialValue])` → `Promise`\n[`Promise.reduce`]: #promisereducearraydynamicpromise-values-function-reducer--dynamic-initialvalue--promise\n\nReduce an array-like, or a promise of an array-like, left-to-right\nusing the provided `reducer` function.\n\nConvenience method for:\n```js\nPromise.resolve(values).reduce(reducer /*, initialValue*/);\n```\n\nSee [`Promise#reduce`].\n\u003chr\u003e\n\n#### `Promise#reduce(Function reducer [, dynamic initialValue])` → `Promise`\n[`Promise#reduce`]: #promisereducefunction-reducer--dynamic-initialvalue--promise\n\nReduce an array, or a promise of an array, which contains a promises\n(or a mix of promises and values) left-to-right with the given\n`reducer` function with the signature `(previousValue, currentValue,\nindex, array)` where `currentValue` is the resolved value of a\nrespective promise in the input array, and `previousValue` is the\nvalue returned by the previous invocation of the `reducer`.  If the\n`reducer` returns a promise or thenable, it will be resolved and\n`previousValue` will be the resolved value.  The `initialValue` may\nalso be a promise or thenable.  If any promise is rejected (in the\ninput array, an `initialValue`, or a promise returned by `resolved`),\nreturned promise is rejected as well.\n\nPromises are resolved in order: first the initialValue (if any), then\nthe first item in the array, then the returned value from the\n`resolver` (if it is a promise), then the next item in the array, then\nthe next returned value from `resolver`, etc.\n\nFor example: Read given files sequentially while summing their\ncontents as an integer. Each file contains just the text `10`.\n\n```js\nvar readFileAsync = Promise.promisify(fs.readFile, false, fs);\nPromise.reduce([\"file1.txt\", \"file2.txt\", \"file3.txt\"], function(total, fileName) {\n    return readFileAsync(fileName, \"utf8\").then(function(contents) {\n        return total + parseInt(contents, 10);\n    });\n}, 0).then(function(total) {\n    //Total is 30\n});\n```\n\nThe behavior of `reduce` matches\n[`Array.prototype.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)\nas much as possible.  Note that this means that non-array objects are often\naccepted without error, and any object without a length field is treated as a\nzero-length array.  For example,\n`Array.prototype.reduce.call(123, Math.pow, 42)` returns `42`.\n`Promise#reduce` rejects with a `TypeError` if `Array.prototype.reduce`\nwould throw a `TypeError`, for example if you pass a zero-length array without\nan `initialValue`.\n\n*The original array is not modified.*\n\n\u003chr\u003e\n\n#### `Promise.reduceRight(Array\u003cdynamic\u003e|Promise values, Function reducer [, dynamic initialValue])` → `Promise`\n[`Promise.reduceRight`]: #promisereducerightarraydynamicpromise-values-function-reducer--dynamic-initialvalue--promise\n\nReduce an array-like, or a promise of an array-like, right-to-left\nusing the provided `reducer` function.\n\nConvenience method for:\n```js\nPromise.resolve(values).reduceRight(reducer /*, initialValue*/);\n```\n\nSee [`Promise#reduceRight`].\n\u003chr\u003e\n\n#### `Promise#reduceRight(Function reducer [, dynamic initialValue])` → `Promise`\n[`Promise#reduceRight`]: #promisereducerightfunction-reducer--dynamic-initialvalue--promise\n\nReduce an array, or a promise of an array, which contains a promises\n(or a mix of promises and values) right-to-left with the given\n`reducer` function with the signature `(previousValue, currentValue,\nindex, array)` where `currentValue` is the resolved value of a\nrespective promise in the input array, and `previousValue` is the\nvalue returned by the previous invocation of the `reducer`.  If the\n`reducer` returns a promise or thenable, it will be resolved and\n`previousValue` will be the resolved value.  The `initialValue` may\nalso be a promise or thenable.  If any promise is rejected (in the\ninput array, an `initialValue`, or a promise returned by `resolved`),\nreturned promise is rejected as well.\n\nPromises are resolved in order: first the initialValue (if any), then\nthe last item in the array, then the returned value from the\n`resolver` (if it is a promise), then the next-to-last item in the array, then\nthe next returned value from `resolver`, etc.\n\nThe behavior of `reduceRight` matches\n[`Array.prototype.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight)\nas much as possible.  Note that this means that non-array objects are often\naccepted without error, and any object without a length field is treated as a\nzero-length array.  For example,\n`Array.prototype.reduceRight.call(123, Math.pow, 42)` returns `42`.\n`Promise#reduceRight` rejects with a `TypeError` if `Array.prototype.reduceRight`\nwould throw a `TypeError`, for example if you pass a zero-length array without\nan `initialValue`.\n\n*The original array is not modified.*\n\n\u003chr\u003e\n\n#### `Promise#spread([Function fulfilledHandler] [, Function rejectedHandler ])` → `Promise`\n[`Promise#spread`]: #promisespreadfunction-fulfilledhandler--function-rejectedhandler---promise\n\nLike calling `Promise#then`, but the fulfillment value or rejection reason is\nassumed to be an array, which is flattened to the formal parameters of\nthe handlers.\n\n```js\nPromise.all([task1, task2, task3]).spread(function(result1, result2, result3){\n\n});\n```\n\nNormally when using `Promise#then` the code would be like:\n\n```js\nPromise.all([task1, task2, task3]).then(function(results){\n    var result1 = results[0];\n    var result2 = results[1];\n    var result3 = results[2];\n});\n```\n\nThis is useful when the `results` array contains items that are not\nconceptually items of the same list.\n\n\u003chr\u003e\n\n### Utility\n\nShorthands for common operations.\n\n##### `Promise.bind(dynamic thisArg)` -\u003e `Promise`\n[`Promise.bind`]: #promisebinddynamic-thisarg---promise\n\nSugar for `Promise.resolve(undefined).bind(thisArg);`.\nSee [`Promise#bind`].\n\n\u003chr\u003e\n\n##### `Promise#bind(dynamic thisArg)` -\u003e `Promise`\n[`Promise#bind`]: #promisebinddynamic-thisarg---promise-1\n\nCreate a promise that follows this promise, but is bound to the given\n`thisArg` value. A bound promise will call its handlers with `this`\nset to the bound value. Additionally promises derived from a bound\npromise will also be bound promises with the same `thisArg` binding as\nthe original promise.\n\n\u003chr\u003e\n\nWithout arrow functions that provide lexical `this`, the\ncorrespondence between async and sync code breaks down when writing\nobject-oriented code. The `Promise#bind` method alleviates this.\n\nConsider:\n\n```js\nMyClass.prototype.method = function() {\n    try {\n        var contents = fs.readFileSync(this.file);\n        var url = urlParse(contents);\n        var result = this.httpGetSync(url);\n        var refined = this.refine(result);\n        return this.writeRefinedSync(refined);\n    }\n    catch (e) {\n        this.error(e.stack);\n    }\n};\n```\n\nThe above has a direct translation:\n\n```js\nMyClass.prototype.method = function() {\n    return fs.readFileAsync(this.file).bind(this)\n    .then(function(contents) {\n        var url = urlParse(contents);\n        return this.httpGetAsync(url);\n    }).then(function(result){\n        var refined = this.refine(result);\n        return this.writeRefinedAsync(refined);\n    }).catch(function(e){\n        this.error(e.stack);\n    });\n};\n```\n\n`Promise#bind` also has a useful side purpose --- promise handlers don't\nneed to share a function to use shared state:\n\n```js\nsomethingAsync().bind({})\n.then(function (aValue, bValue) {\n    this.aValue = aValue;\n    this.bValue = bValue;\n    return somethingElseAsync(aValue, bValue);\n}).then(function (cValue) {\n    return this.aValue + this.bValue + cValue;\n});\n```\n\nThe above without `Promise#bind` could be achieved with:\n\n```js\nvar scope = {};\nsomethingAsync()\n.then(function (aValue, bValue) {\n    scope.aValue = aValue;\n    scope.bValue = bValue;\n    return somethingElseAsync(aValue, bValue);\n}).then(function (cValue) {\n    return scope.aValue + scope.bValue + cValue;\n});\n```\n\nHowever, there are many differences when you look closer:\n\n- Requires a statement so cannot be used in an expression context.\n- If not there already, an additional wrapper function is required to\n  avoid leaking or sharing `scope`.\n- The handler functions are now closures, thus less efficient and not\n  reusable.\n\n\u003chr\u003e\n\nNote that bind is only propagated with promise transformation. If you\ncreate new promise chains inside a handler, those chains are not bound\nto the \"outer\" `this`:\n\n```js\nsomething().bind(var1).then(function(){\n    //`this` is var1 here\n    return Promise.all(getStuff()).then(function(results){\n        //`this` is undefined here\n        //refine results here etc\n    });\n}).then(function(){\n    //`this` is var1 here\n});\n```\n\nIf you don't want to return a bound promise to the consumers of a\npromise, you can rebind the chain at the end:\n\n```js\nMyClass.prototype.method = function() {\n    return fs.readFileAsync(this.file).bind(this)\n    .then(function(contents) {\n        var url = urlParse(contents);\n        return this.httpGetAsync(url);\n    }).then(function(result){\n        var refined = this.refine(result);\n        return this.writeRefinedAsync(refined);\n    }).catch(function(e){\n        this.error(e.stack);\n    }).bind(); // Unbind the promise.\n};\n```\n\nRebinding can also be abused to do something gratuitous like this:\n\n```js\nPromise.resolve(\"my-element\")\n    .bind(document)\n    .then(document.getElementById)\n    .bind(console)\n    .then(console.log);\n```\n\nThe above does `console.log(document.getElementById(\"my-element\"));`.\n\n\u003chr\u003e\n\n#### `Promise#call(String propertyName [, Promise|dynamic arg...])` → `Promise`\n[`Promise#call`]: #promisecallstring-propertyname--promisedynamic-arg--promise\n\nThis is a convenience method for doing:\n\n```js\npromise.then(function(obj){\n    return obj[propertyName].call(obj, arg...);\n});\n```\nIf any of the `arg...` are Promises, they will be resolved before the method\nis invoked.\n\n\u003chr\u003e\n\n#### `Promise#get(String propertyName)` → `Promise`\n[`Promise#get`]: #promisegetstring-propertyname--promise\n\nThis is a convenience method for doing:\n\n```js\npromise.then(function(obj){\n    return obj[propertyName];\n});\n```\n\n\u003chr\u003e\n\n#### `Promise#return(Promise|dynamic value)` → `Promise`\n[`Promise#return`]: #promisereturnpromisedynamic-value--promise\n\nConvenience method for:\n\n```js\npromise.then(function() {\n   return value;\n});\n```\n\nin the case where `value` doesn't change its value.\n\nThat means `value` is bound at the time of calling `Promise#return`\nso this will not work as expected:\n\n```js\nfunction getData() {\n    var data;\n\n    return query().then(function(result) {\n        data = result;\n    }).return(data);\n}\n```\n\nbecause `data` is `undefined` at the time `.return` is called.\n\n\u003chr\u003e\n\n#### `Promise#tap(Function handler)` → `Promise`\n[`Promise#tap`]: #promisetapfunction-handler--promise\n\nConvenience method for:\n\n```js\npromise.then(function(value) {\n   return Promise.resolve(handler(value)).return(value);\n});\n```\n\nThat is, it waits for the promise, then invokes the handler with the\npromised value.  It waits for any promise returned by the handler, then\nreturns the original value.\n\nCommon use case is to add logging to an existing promise chain:\n\n```js\ndoSomething()\n    .then(...)\n    .then(...)\n    .tap(console.log)\n    .then(...)\n    .then(...)\n```\n\n\u003chr\u003e\n\n#### `Promise#then0([Function onFulfilled [, Function onRejected]])` → `undefined`\n[`Promise#then0`]: #promisethen0function-onFulfilled--undefined\n\nThis is identical to `Promise#then` except that it does not return\na value.  Some `Promise` implementations (for example, [babybird])\nexport a `then0` implementation which is substantially faster than\ncalling `Promise#then`.  If such an implementation is present, its\nimplementation will be used.  Otherwise `prfun` will provide a\nshim implementation that just calls `Promise#then` and discards\nthe result.\n\nThis allows you to use `then0` freely in your own code whenever\nyou don't care about the result, and `prfun` will use the most\nefficient implementation available.\n\n\u003chr\u003e\n\n#### `Promise#throw(Promise|dynamic reason)` → `Promise`\n[`Promise#throw`]: #promisethrowpromisedynamic-reason--promise\n\nConvenience method for:\n\n```js\npromise.then(function() {\n   throw reason;\n});\n```\n...except that `reason` is first resolved, if it is a `Promise` or thenable.\n\nSame limitations apply as with [`Promise#return`].\n\n\u003chr\u003e\n\n#### `Promise.defer()` → `PromiseResolver`\n[`Promise.defer`]: #promisedefer--promiseresolver\n\nCreate a promise with undecided fate and return a `PromiseResolver` to\ncontrol it.\n\nThe use of `Promise.defer` is discouraged---it is much more awkward\nand error-prone than using `new Promise`.  It is provided only for\ncompatibility with older libraries like [q], [when], etc.\n\nA `PromiseResolver` contains three fields: `promise`, `resolve`, and\n`reject`.  It also contains two additional helpers, which are\nimplemented as getters: `resolver` and `callback`.  The `resolver`\nproperty returns an object with only `resolve` and `reject` fields, as\nin the [when] package.  The `callback` property returns a node-style\ncallback function with signature `(err, result)` which will invoke\n`reject` and `resolve` as appropriate.  This is like the `callback`\nproperty in [bluebird] or the result of `makeNodeResolver` in [q].\n\n\u003chr\u003e\n\n#### `Promise#done()` → `undefined`\n[`Promise#done`]: #promisedone--undefined\n\nTerminate a chain of promises, ensuring that any unhandled rejections\nare rethrown so as to trigger the top-level unhandled exception\nhandler (which will typically result in a message on console).\n\nThe use of `Promise#done` is discouraged---it is hoped that future\npromise implementations [will provide special development tools to track orphaned promises](https://github.com/domenic/promises-unwrapping/issues/19).\nThis method is provided for compatibility with older libraries,\nand as a make-do until better debugging tools are integrated\ninto JavaScript engines.\n\n\u003chr\u003e\n\n### Try/caught/finally\n\n#### `Promise.try(Function fn [, dynamic ctx [, dynamic args...]] )` → `Promise`\n[`Promise.try`]: #promisetryfunction-fn--dynamic-ctx--dynamic-args---promise\n\nStart the chain of promises with `Promise.try`. Any synchronous\nexceptions will be turned into rejections on the returned promise.\n\n```js\nfunction getUserById(id) {\n    return Promise.try(function(){\n        if (typeof id !== \"number\") {\n            throw new Error(\"id must be a number\");\n        }\n        return db.getUserById(id);\n    });\n}\n```\n\nNow if someone uses this function, they will catch all errors in their\nPromise `.catch` handlers instead of having to handle both synchronous\nand asynchronous exception flows.\n\nIf provided, `ctx` becomes the `this` value for the function call.  If\nit is a promise, it is first resolved.  Any `args` provided are\nresolved (if they are promises) and passed as arguments to the\nfunction call.\n\n\u003chr\u003e\n\n#### `Promise#caught([Function ErrorClass|Function predicate...], Function handler)` → `Promise`\n[`Promise#caught`]: #promisecaughtfunction-errorclassfunction-predicate-function-handler--promise\n\nThis extends `.catch` to work more like catch-clauses in languages\nlike Java or C#. Instead of manually checking `instanceof` or\n`.name === \"SomeError\"`, you may specify a number of error constructors which\nare eligible for this catch handler. The catch handler that is first\nmet that has eligible constructors specified, is the one that will be\ncalled.\n\nExample:\n\n```js\nsomePromise.then(function(){\n    return a.b.c.d();\n}).caught(TypeError, function(e){\n    //If a is defined, will end up here because\n    //it is a type error to reference property of undefined\n}).caught(ReferenceError, function(e){\n    //Will end up here if a wasn't defined at all\n}).caught(function(e){\n    //Generic catch-the rest, error wasn't TypeError nor\n    //ReferenceError\n});\n ```\n\nYou may also add multiple filters for a catch handler:\n\n```js\nsomePromise.then(function(){\n    return a.b.c.d();\n}).caught(TypeError, ReferenceError, function(e){\n    //Will end up here on programmer error\n}).caught(NetworkError, TimeoutError, function(e){\n    //Will end up here on expected everyday network errors\n}).catch(function(e){\n    //Catch any unexpected errors\n});\n```\n\nFor a parameter to be considered a type of error that you want to\nfilter, you need the constructor to have its `.prototype` property be\n`instanceof Error`.\n\nSuch a constructor can be minimally created like so:\n\n```js\nfunction MyCustomError() {}\nMyCustomError.prototype = Object.create(Error.prototype);\n```\n\nUsing it:\n\n```js\nPromise.resolve().then(function(){\n    throw new MyCustomError();\n}).caught(MyCustomError, function(e){\n    //will end up here now\n});\n```\n\nHowever, you can obtain better stack traces and string output with:\n\n```js\nfunction MyCustomError(message) {\n    this.message = message;\n    this.name = \"MyCustomError\";\n    if (Error.captureStackTrace) // v8 environments\n        Error.captureStackTrace(this, MyCustomError);\n}\nMyCustomError.prototype = Object.create(Error.prototype);\nMyCustomError.prototype.constructor = MyCustomError;\n```\n\nUsing CoffeeScript's `class` for the same:\n\n```coffee\nclass MyCustomError extends Error\n  constructor: (@message) -\u003e\n    @name = \"MyCustomError\"\n    Error.captureStackTrace?(this, MyCustomError)\n```\n\nThis method also supports predicate-based filters. If you pass a\npredicate function instead of an error constructor, the predicate will\nreceive the error as an argument. The return result of the predicate\nwill be used determine whether the error handler should be called.\n\nPredicates should allow for very fine grained control over caught\nerrors: pattern matching, error-type sets with set operations and many\nother techniques can be implemented on top of them.\n\nExample of using a predicate-based filter:\n\n```js\nvar request = Promise.promisify(require(\"request\"), ['response', 'body']);\n\nfunction clientError(e) {\n    return e.code \u003e= 400 \u0026\u0026 e.code \u003c 500;\n}\n\nrequest(\"http://www.google.com\").then(function(result) {\n    console.log(result.body);\n}).caught(clientError, function(e){\n   //A client error like 400 Bad Request happened\n});\n```\n\n\u003chr\u003e\n\n#### `Promise#finally(Function handler)` → `Promise`\n[`Promise#finally`]: #promisefinallyfunction-handler--promise\n\nPass a handler that will be called regardless of this promise's\nfate. Returns a new promise chained from this promise, which will\nbecome resolved with the same fulfillment value or rejection reason as\nthis promise. However, if `handler` returns a promise, the resolution\nof the returned promise will be delayed until the promise returned\nfrom `handler` is finished.  If `handler` throws an exception or\nreturns a rejected promise, the returned promise will reject in the\nsame way.  (This matches the JavaScript semantics for exceptions\nthrown inside `finally` clauses.)\n\nConsider the example:\n\n```js\nfunction anyway() {\n    $(\"#ajax-loader-animation\").hide();\n}\n\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    }).then(anyway, anyway);\n}\n```\n\nThis example doesn't work as intended because the `then` handler\nactually swallows the exception and returns `undefined` for any\nfurther chainers.\n\nThe situation can be fixed with `Promise#finally`:\n\n```js\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    }).finally(function(){\n        $(\"#ajax-loader-animation\").hide();\n    });\n}\n```\n\nNow the animation is hidden but an exception or the actual return\nvalue will automatically skip the finally and propagate to further\nchainers. This is more in line with the synchronous `finally` keyword.\n\n`Promise#finally` works like [Q's finally method](https://github.com/kriskowal/q/wiki/API-Reference#wiki-promisefinallycallback), unless `callback` returns a rejected promise.\n\nNote that the parallel with synchronous `finally` is not exact:\n```js\n// as expected:\n(function() { try { return 1; } finally { throw \"2\"; } })(); // throws \"2\"\nPromise.resolve(1).finally(function() { throw \"2\"; }); // rejects with \"2\"\n\n// but:\n(function() { try { return 1; } finally { return 2; } })(); // returns 2\nPromise.resolve(1).finally(function() { return 2; }); // resolves to '1'\n\n// compare:\n(function() { try { return 1; } finally { 2; } })(); // returns 1\n```\n\nThis asymmetry is because the `Promise` API can't distinguish the `return`\nstatement from an expression evaluating to a value.\n\n\u003chr\u003e\n\n### Method wrappers and helpers\n\nFunctions for writing promise-returning methods.\n\n#### `Promise.guard(Function|Number condition, Function fn)` → `Function`\n[`Promise.guard`]: #promiseguardfunctionnumber-condition-function-fn--function\n\nLimit the concurrency of a function `fn`.  Creates a new function\nwhose concurrency is limited by `condition`.  This can be useful with\noperations such as [`Promise.map`], [`Promise.all`], etc that allow\ntasks to execute in \"parallel\", to limit the number which can be\nin-flight simultanously.\n\nThe `condition` argument is a concurrency limiting condition, such as\n[`Promise.guard.n`].  If `condition` is a number, it will be treated\nas if it were `Promise.guard.n(condition)`.\n\nExample:\n```js\n// Using Promise.guard with Promise.map to limit concurrency\n// of the mapFunc\n\nvar guardedAsyncOperation, mapped;\n\n// Allow only 1 inflight execution of guarded\nguardedAsyncOperation = Promise.guard(1, asyncOperation);\n\nmapped = Promise.map(array, guardedAsyncOperation);\nmapped.then(function(results) {\n    // Handle results as usual\n});\n```\n\nExample:\n```js\n// Using Promise.guard with Promise.all to limit concurrency\n// across *all tasks*\n\nvar guardTask, tasks, taskResults;\n\ntasks = [/* Array of async functions to execute as tasks */];\n\n// Use bind() to create a guard that can be applied to any function\n// Only 2 tasks may execute simultaneously.\n// Note that all guarded tasks share the same condition instance\n// (`Promise.guard.n(2)`) -- if we had passed `2` instead they\n// would each have their own guard, which wouldn't do what we want.\nguardTask = Promise.guard.bind(Promise, Promise.guard.n(2));\n\n// Use guardTask to guard all the tasks.\ntasks = tasks.map(guardTask);\n\n// Execute the tasks with concurrency/\"parallelism\" limited to 2\ntaskResults = Promise.all(tasks);\ntaskResults.then(function(results) {\n    // Handle results as usual\n});\n```\n\n##### `Promise.guard.n(Number number)` → `Function`\n[`Promise.guard.n`]: #promiseguardnnumber-number--function\n\nCreates a condition that allows at most `number` of simultaneous executions inflight.\n\n```js\nvar condition = Promise.guard.n(number);\n```\n\n#### `Promise.method(Function fn)` → `Function`\n[`Promise.method`]: #promisemethodfunction-fn--function\n\nReturns a new function that wraps the given function `fn`. The new\nfunction will always return a promise that is fulfilled with the\noriginal function's return value or rejected with thrown exceptions\nfrom the original function.  It will also unwrap any arguments\n(including `this`) which are promises, converting them to their\nfulfilled values.\n\nThis method is convenient when a function can sometimes return\nsynchronously or throw synchronously.\n\nExample without using `Promise.method`:\n\n```js\nMyClass.prototype.method = function(input) {\n    if (!this.isValid(input)) {\n        return Promise.reject(new TypeError(\"input is not valid\"));\n    }\n\n    if (this.cache(input)) {\n        return Promise.resolve(this.someCachedValue);\n    }\n\n    return db.queryAsync(input).bind(this).then(function(value) {\n        this.someCachedValue = value;\n        return value;\n    });\n};\n```\n\nUsing `Promise.method`, there is no need to manually wrap direct\nreturn or throw values into a promise:\n\n```js\nMyClass.prototype.method = Promise.method(function(input) {\n    if (!this.isValid(input)) {\n        throw new TypeError(\"input is not valid\");\n    }\n\n    if (this.cachedFor(input)) {\n        return this.someCachedValue;\n    }\n\n    return db.queryAsync(input).bind(this).then(function(value) {\n        this.someCachedValue = value;\n        return value;\n    });\n});\n```\n\nSee also [`Q.promised`](https://github.com/kriskowal/q/wiki/API-Reference#wiki-qpromisedfunc),\n[`when.lift`](https://github.com/cujojs/when/blob/master/docs/api.md#whenlift).\n\n\u003chr\u003e\n\n#### `Promise#nodify([Function callback])` → `Promise`\n[`Promise#nodify`]: #promisenodifyfunction-callback--promise\n\nRegister a node-style callback on this promise. When this promise is\nis either fulfilled or rejected, the node callback will be called back\nwith the node.js convention, where error reason is the first argument\nand success value is the sec ond argument. The error argument will be\n`null` in case of success.\n\nReturns back this promise instead of creating a new one. If the\n`callback` argument is not a function, this method does not do\nanything.\n\nThis can be used to create APIs that both accept node-style callbacks\nand return promises:\n\n```js\nfunction getDataFor(input, callback) {\n    return dataFromDataBase(input).nodify(callback);\n}\n```\n\nThe above function can then make everyone happy.\n\nPromises:\n\n```js\ngetDataFor(\"me\").then(function(dataForMe) {\n    console.log(dataForMe);\n});\n```\n\nNormal callbacks:\n\n```js\ngetDataFor(\"me\", function(err, dataForMe) {\n    if( err ) {\n        console.error( err );\n    } else {\n        console.log(dataForMe);\n    }\n});\n```\n\n\u003chr\u003e\n\n#### `Promise.promisify(Function nodeFunction [, dynamic pattern [, dynamic receiver]])` → `Function`\n[`Promise.promisify`]: #promisepromisifyfunction-nodefunction--dynamic-pattern--dynamic-receiver--function\n\nReturns a function that will wrap the given `nodeFunction`. Instead of\ntaking a callback, the returned function will return a promise whose\nfate is decided by the callback behavior of the given node\nfunction. The node function should conform to node.js convention of\naccepting a callback as last argument and calling that callback with\nerror as the first argument and success value(s) in the second and\nfollowing arguments.\n\nIf the `pattern` is `true`, the fulfillment value will be an array\ncontaining the callback arguments.\n\nIf the `pattern` is not present or falsy, the fulfillment value will\nbe the second value passed to the callback.  (This is useful in the\ncommon case where only a single value is provided to the callback.)\n\nIf the `pattern` is an array of names, the fulfillment value will be\nan object with the callback arguments assigned to named fields in the\norder given by `pattern`.\n\nIf you pass a `receiver`, the `nodeFunction` will be called as a\nmethod on the `receiver` (that is, `this` will be set to `receiver` when\n`nodeFunction` is invoked).\n\nExample of promisifying the asynchronous `readFile` of node.js `fs`-module:\n\n```js\nvar fs = require('fs');\nvar readFile = Promise.promisify(fs.readFile, false, fs);\n\nreadFile(\"myfile.js\", \"utf8\").then(function(contents){\n    return eval(contents);\n}).then(function(result){\n    console.log(\"The result of evaluating myfile.js\", result);\n}).caught(SyntaxError, function(e){\n    console.log(\"File had syntax error\", e);\n//Catch any other error\n}).catch(function(e){\n    console.log(\"Error reading file\", e);\n});\n```\n\n**Tip**\n\nUse [`Promise#spread`] with APIs that have multiple success values:\n\n```js\nvar request = Promise.promisify(require('request'), true);\nrequest(\"http://www.google.com\").spread(function(response, body) {\n    console.log(body);\n}).catch(function(err) {\n    console.error(err);\n});\n```\n\nThe above uses the [request](https://github.com/mikeal/request)\nlibrary which has a callback signature of multiple success values.\n\nSince `prfun` version 1.0.0.\n\u003chr\u003e\n\n### Timers\n\nMethods to delay and time out promises.\n\n#### `Promise.delay([dynamic value,] int ms)` → `Promise`\n[`Promise.delay`]: #promisedelaydynamic-value-int-ms--promise\n\nReturns a promise that will be fulfilled with `value` (or `undefined`)\nafter given `ms` milliseconds. If `value` is a promise, the delay will\nstart counting down when it is fulfilled and the returned promise will\nbe fulfilled with the fulfillment value of the `value` promise.\n\n```js\nPromise.delay(500).then(function(){\n    console.log(\"500 ms passed\");\n    return \"Hello world\";\n}).delay(500).then(function(helloWorldString) {\n    console.log(helloWorldString);\n    console.log(\"another 500 ms passed\") ;\n});\n```\n\n\u003chr\u003e\n\n#### `Promise#delay(int ms)` → `Promise`\n[`Promise#delay`]: #promisedelayint-ms--promise\n\nConvenience method for:\n```js\nPromise.delay(this, ms);\n```\n\nSee [`Promise.delay`].\n\n\u003chr\u003e\n\n#### `Promise#timeout(int ms [, String message])` → `Promise`\n[`Promise#timeout`]: #promisetimeoutint-ms--string-message--promise\n\nReturns a promise that will be fulfilled with this promise's\nfulfillment value or rejection reason. However, if this promise is not\nfulfilled or rejected within `ms` milliseconds, the returned promise\nis rejected with a `Promise.TimeoutError` instance.\n\nYou may specify a custom error message with the `message` parameter.\n\nThe example function `fetchContent` tries to fetch the contents of a\nweb page with a 50ms timeout and sleeping 100ms between each retry. If\nthere is no response after 5 retries, then the returned promise is\nrejected with a `ServerError` (made up error type).\n\n```js\nfunction fetchContent(retries) {\n    if (!retries) retries = 0;\n    var jqXHR = $.get(\"http://www.slowpage.com\");\n    //Cast the jQuery promise into a bluebird promise\n    return Promise.resolve(jqXHR)\n        .timeout(50)\n        .caught(Promise.TimeoutError, function() {\n            if (retries \u003c 5) {\n                return Promise.delay(100).then(function(){\n                    return fetchContent(retries+1);\n                });\n            } else {\n                throw new ServerError(\"not responding after 5 retries\");\n            }\n        });\n}\n```\n\n\u003chr\u003e\n\n### Generators\n\nUsing ECMAScript6 generators feature to implement better syntax for promises.\n\n**Note**: Requires an environment that supports ES6 generators\nand the `yield` keyword.  Node \u003e= `0.11.2` with the `--harmony-generators`\ncommand-line flag will work, or Node \u003e= `4` with no special flags.\n\n#### `Promise.async(GeneratorFunction generatorFunction [, int cbArg])` → `Function`\n[`Promise.async`]: #promiseasyncgeneratorfunction-generatorfunction--int-cbarg--function\n\nTakes a function that can use `yield` to await the resolution of\npromises while control is transferred back to the JS event loop.  You\ncan write code that looks and acts like synchronous code, even using\nsynchronous `try`, `catch` and `finally`.  Returns a function which\nreturns a `Promise`.\n\nIf the optional `cbArg` is present, then `Promise.nodify` is invoked\non the result with the given (optional) argument as a parameter.\n\n```js\n// Use Promise.async to create a function that returns a Promise\nvar getRecentTodosForUser = Promise.async(function*(todosFilter, userId) {\n    var todos = yield getTodosForUser(userId);\n    return todos.filter(todosFilter);\n});\n\nfunction getTodosForUser(userId) {\n    // returns a promise for an array of the user's todos\n}\n\n// Get (a promise for) the todos for user 123, and filter them\n// using the `isRecentTodo` filter.\nvar filteredTodos = getRecentTodosForUser(isRecentTodo, 123);\n\nfilteredTodos.then(showTodos, showError);\n```\n\nIn addition to `try`, `catch`, and `finally`, `return` also works as\nexpected.  In this revised example, `yield` allows us to return a\nresult and move error handling out to the caller.\n\n```js\n// Use Promise.async to create a function that returns a Promise\nvar getRecentTodosForUser = Promise.async(function*(todosFilter, userId) {\n    var todos;\n    try {\n        todos = yield getTodosForUser(userId);\n        showTodos(todos.filter(todosFilter));\n    } catch(e) {\n        showError(e);\n    }\n});\n\nfunction getTodosForUser(userId) {\n    // returns a promise for an array of the user's todos\n}\n\n// Get (a promise for) the todos for user 123, and filter them\n// using the `isRecentTodo` filter.\nvar filteredTodos = getRecentTodosForUser(isRecentTodo, 123);\n```\n\nHowever, note the difference between `func1` and `func2` in the following:\n\n```js\nvar thrower = Promise.method(function(msg) { throw new Error(msg); });\n\nvar func1 = Promise.async(function *() {\n    try {\n        return thrower(\"hey\");\n    } catch (e) {\n        console.log(\"This line is never reached.\");\n    }\n});\n\nvar func2 = Promise.async(function *() {\n    try {\n        return (yield thrower(\"ho\"));\n    } catch (e) {\n        console.log(\"Exception is caught here!\", e);\n    }\n});\n```\n\nWhen `func1` returns a `Promise`, we leave the scope of the try block.\nBy the time the returned `Promise` rejects with an error, we can no longer\ncatch it.\n\nIf you want to ensure that rejected `Promise`s get a chance to be caught,\nbe sure to `yield` them (which resolves the `Promise` completely) before\nreturning, as in `func2`.\n\nYou can also use `Promise.async` to implement coroutines:\n\n```js\nfunction PingPong() { }\n\nPingPong.prototype.ping = Promise.async(function* (val) {\n    console.log(\"Ping?\", val)\n    yield Promise.delay(500)\n    this.pong(val+1)\n});\n\nPingPong.prototype.pong = Promise.async(function* (val) {\n    console.log(\"Pong!\", val)\n    yield Promise.delay(500);\n    this.ping(val+1)\n});\n\nvar a = new PingPong();\na.ping(0);\n```\n\nRunning the example with node version at least `0.11.2`:\n\n    $ node --harmony test.js\n    Ping? 0\n    Pong! 1\n    Ping? 2\n    Pong! 3\n    Ping? 4\n    ...\n\n**Tip**\n\nYou can use [`Promise.join`] to wait for multiple promises at once.\n\nYou can combine it with ES6 destructuring for some neat syntax:\n\n```js\nvar getData = Promise.async(function* (urlA, urlB) {\n    [resultA, resultB] = yield Promise.join(http.getAsync(urlA), http.getAsync(urlB));\n    //use resultA\n    //use resultB\n});\n```\n\nYou might wonder why not just do this?\n\n```js\nvar getData = Promise.async(function* (urlA, urlB) {\n    var resultA = yield http.getAsync(urlA);\n    var resultB = yield http.getAsync(urlB);\n});\n```\n\nThe problem with the above is that the requests are not done in\nparallel. It will completely wait for request A to complete before\neven starting request B. In the example with [`Promise.join`] both\nrequests fire off at the same time in parallel.\n\n**Legacy callbacks**\n\nFor compatibility with legacy code which uses callbacks, you can\nuse the optional `cbArg`, as follows:\n\n```js\nvar getDataFor = Promise.async(function *(input) {\n  return dataFromDataBase(input);\n}, 1 /* arg #1 is optional callback */);\n\n/* Calling this using node 'callback' syntax */\ngetDataFor(input, function(err, dataForMe) {\n    if (err) {\n        console.error( err );\n    } else {\n        console.log(dataForMe);\n    }\n});\n```\n\n**See also**\n\nThe\n[`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\nfunctions and\n[`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\noperator available in Node \u003e= `7.6` are compatible with `Promise.async` and\n`yield`.  It should be straightforward to do a search-and-replace in your\ncodebase once your minimum node version permits.\n\nSee also [`Q.async`](https://github.com/kriskowal/q/wiki/API-Reference#wiki-qasyncgeneratorfunction).\n\n\n\u003chr\u003e\n\n\n## License\n\nCopyright (c) 2014-2018 C. Scott Ananian\n\nPortions are Copyright (c) 2014 Petka Antonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\u003c/p\u003e\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n[ES6]:      http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts\n[bluebird]: https://github.com/petkaantonov/bluebird\n[when]:     https://github.com/cujojs/when\n[q]:        https://github.com/kriskowal/q\n[es6-shim]: https://github.com/paulmillr/es6-shim\n[core-js]:  https://github.com/zloirock/core-js\n[babybird]: https://github.com/cscott/babybird\n\n[NPM1]: https://nodei.co/npm/prfun.png\n[NPM2]: https://nodei.co/npm/prfun/\n\n[1]: https://travis-ci.org/cscott/prfun.png\n[2]: https://travis-ci.org/cscott/prfun\n[3]: https://david-dm.org/cscott/prfun.png\n[4]: https://david-dm.org/cscott/prfun\n[5]: https://david-dm.org/cscott/prfun/dev-status.png\n[6]: https://david-dm.org/cscott/prfun#info=devDependencies\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcscott%2Fprfun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcscott%2Fprfun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcscott%2Fprfun/lists"}