{
  "name": "async-patterns",
  "version": "3.0.2",
  "description": "A a collection of design patterns for async/await or promise-driven async code",
  "repository": {
    "type": "git",
    "url": "git://github.com/somesocks/async-patterns.git"
  },
  "keywords": [
    "async",
    "callbacks"
  ],
  "author": "James Larsen (somesocks@gmail.com)",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/somesocks/async-patterns/issues"
  },
  "homepage": "https://github.com/somesocks/async-patterns",
  "dependencies": {
    "callback-patterns": "^3.0.0"
  },
  "devDependencies": {
    "@types/mocha": "9.1.0",
    "@typescript-eslint/eslint-plugin": "5.12.1",
    "@typescript-eslint/parser": "5.12.1",
    "eslint": "8.9.0",
    "jsdoc-to-markdown": "7.1.1",
    "mocha": "9.2.1",
    "ping": "^0.2.2",
    "typescript": "^4.5.5",
    "vet": "4.3.1"
  },
  "scripts": {},
  "readme": "# async-patterns\n\n`async-patterns` is a collection of design patterns for async/await or promise-driven async code.  The design patterns in this library are constructors that build callback-expecting functions.  Each pattern is designed to be a stand-alone piece of code, tested for performance and robustness.\n\n## API\n\n<a name=\"async-patterns\"></a>\n\n## async-patterns : <code>object</code>\nA namespace.\n\n**Kind**: global namespace  \n\n* [async-patterns](#async-patterns) : <code>object</code>\n    * [.Callbackify](#async-patterns.Callbackify) ⇒ <code>function</code>\n    * [.CatchError](#async-patterns.CatchError) ⇒ <code>function</code>\n    * [.InOrder](#async-patterns.InOrder) ⇒ <code>function</code>\n    * [.InParallel](#async-patterns.InParallel) ⇒ <code>function</code>\n    * [.InSeries](#async-patterns.InSeries) ⇒ <code>function</code>\n    * [.LogError](#async-patterns.LogError) ⇒ <code>function</code>\n    * [.ParallelFilter](#async-patterns.ParallelFilter) ⇒ <code>function</code>\n    * [.ParallelMap](#async-patterns.ParallelMap) ⇒ <code>function</code>\n    * [.PassThrough](#async-patterns.PassThrough)\n    * [.Promisify](#async-patterns.Promisify) ⇒ <code>function</code>\n    * [.Race](#async-patterns.Race) ⇒ <code>function</code>\n    * [.testing](#async-patterns.testing) : <code>object</code>\n        * [.AssertionTest](#async-patterns.testing.AssertionTest)\n            * [new AssertionTest()](#new_async-patterns.testing.AssertionTest_new)\n            * [assertionTest.describe(description)](#async-patterns.testing.AssertionTest+describe) ⇒ <code>AssertionTest</code>\n            * [assertionTest.setup(task)](#async-patterns.testing.AssertionTest+setup) ⇒ <code>AssertionTest</code>\n            * [assertionTest.prepare(task)](#async-patterns.testing.AssertionTest+prepare) ⇒ <code>AssertionTest</code>\n            * [assertionTest.execute(task)](#async-patterns.testing.AssertionTest+execute) ⇒ <code>AssertionTest</code>\n            * [assertionTest.verify(...tasks)](#async-patterns.testing.AssertionTest+verify) ⇒ <code>AssertionTest</code>\n            * [assertionTest.teardown(task)](#async-patterns.testing.AssertionTest+teardown) ⇒ <code>AssertionTest</code>\n            * [assertionTest.build()](#async-patterns.testing.AssertionTest+build) ⇒ <code>function</code>\n            * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n            * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n    * [.unstable](#async-patterns.unstable) : <code>object</code>\n        * [.TraceError(task)](#async-patterns.unstable.TraceError) ⇒ <code>function</code>\n    * [.Assert(validator, message)](#async-patterns.Assert) ⇒ <code>taskFunction</code>\n    * [.Delay(delay)](#async-patterns.Delay) ⇒ <code>taskFunction</code>\n    * [.If(ifTask, thenTask, elseTask)](#async-patterns.If) ⇒ <code>taskFunction</code>\n    * [.Logging(...statements)](#async-patterns.Logging) ⇒ <code>taskFunction</code>\n    * [.Memoize(task, [keyFunction])](#async-patterns.Memoize) ⇒ <code>AsyncTask</code>\n    * [.Retry(task, options)](#async-patterns.Retry) ⇒ <code>taskFunction</code>\n    * [.Throttle(task, limit)](#async-patterns.Throttle) ⇒ <code>taskFunction</code>\n    * [.TimeIn(task, ms)](#async-patterns.TimeIn) ⇒ <code>taskFunction</code>\n    * [.TimeOut(task, ms)](#async-patterns.TimeOut) ⇒ <code>taskFunction</code>\n    * [.Timer(task, label)](#async-patterns.Timer) ⇒ <code>taskFunction</code>\n    * [.While(conditionTask, loopTask)](#async-patterns.While) ⇒ <code>function</code>\n\n\n* * *\n\n<a name=\"async-patterns.Callbackify\"></a>\n\n### async-patterns.Callbackify ⇒ <code>function</code>\n```javascript\n    const task = Callbackify(\n        async (i) => i + 1\n    );\n\n    // logs 'res 1', eventually\n    task(\n        (err, res) => console.log('res', res),\n        0\n    );\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - a callback-expecting function  \n**Params**\n\n- task <code>function</code> - an async function\n\n\n* * *\n\n<a name=\"async-patterns.CatchError\"></a>\n\n### async-patterns.CatchError ⇒ <code>function</code>\n```javascript\n  let task = CatchError(task);\n\n  const { error, result } = await task(request);\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function around the task  \n**Params**\n\n- task <code>function</code> - an async function to wrap around with a catch wrapper.\n\n\n* * *\n\n<a name=\"async-patterns.InOrder\"></a>\n\n### async-patterns.InOrder ⇒ <code>function</code>\n```javascript\n\nlet InOrder = require('async-patterns/InOrder');\n\n\tconst task = InOrder(\n\t\tasync (i) => i + 1,\n\t\tasync (i) => i + 1,\n\t\tasync (i) => i + 1\n\t);\n\n\tawait task(0); // returns 3\n\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function that runs all of the tasks in order, calling each one with original request  \n**Params**\n\n- ...tasks <code>function</code> - any number of async tasks.\n\n\n* * *\n\n<a name=\"async-patterns.InParallel\"></a>\n\n### async-patterns.InParallel ⇒ <code>function</code>\n```javascript\n\nlet InParallel = require('async-patterns/InParallel');\n\n\tconst task = InParallel(\n\t\tasync (i) => i + 1,\n\t\tasync (i) => i + 2,\n\t\tasync (i) => i + 3\n\t);\n\n\tconst results = await task(0); // results is [1, 2, 3]\n\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function that runs all the tasks in parallel, and returns an array of results  \n**Params**\n\n- ...tasks <code>function</code> - any number of async tasks.\n\n\n* * *\n\n<a name=\"async-patterns.InSeries\"></a>\n\n### async-patterns.InSeries ⇒ <code>function</code>\n```javascript\n\nlet InSeries = require('async-patterns/InSeries');\n\n\tconst task = InSeries(\n\t\tasync (i) => i + 1,\n\t\tasync (i) => i + 1,\n\t\tasync (i) => i + 1\n\t);\n\n\tconst results = await task(0); // results is 3\n\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function that runs all of the tasks in series, calling each one with the results of the previous one  \n**Params**\n\n- ...tasks <code>function</code> - any number of async tasks.\n\n\n* * *\n\n<a name=\"async-patterns.LogError\"></a>\n\n### async-patterns.LogError ⇒ <code>function</code>\n```javascript\n  let task = LogError(task);\n\n  // if an error occurs, it will be logged before getting re-thrown here\n  const result = await task(request);\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function around the task  \n**Params**\n\n- task <code>function</code> - an async function to wrap around with a error logging wrapper.\n\n\n* * *\n\n<a name=\"async-patterns.ParallelFilter\"></a>\n\n### async-patterns.ParallelFilter ⇒ <code>function</code>\n```javascript\n    const task = ParallelFilter(\n        async (val, i) => val % 2 === 0\n    );\n\n    const results = await task([0, 1, 2]); // results is [0, 2]\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function that takes in an array of requests, runs the task in parallel, once for each input in the array, and returns an array of results  \n**Params**\n\n- task <code>function</code> - the filtering task\n\n\n* * *\n\n<a name=\"async-patterns.ParallelMap\"></a>\n\n### async-patterns.ParallelMap ⇒ <code>function</code>\n```javascript\n    const task = ParallelMap(\n        async (val, i) => val + 1\n    );\n\n    const results = await task([0, 1, 2]); // results is [1, 2, 3]\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async wrapper function that takes in an array of requests, runs the task in parallel, once for each input in the array, and returns an array of results  \n**Params**\n\n- task <code>function</code> - the mapping task\n\n\n* * *\n\n<a name=\"async-patterns.PassThrough\"></a>\n\n### async-patterns.PassThrough\n```javascript\n    const task = PassThrough;\n\n    const results = await task(0); // results is 0\n```\n\nPassThrough does nothing, just passes the request through as the result\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n\n* * *\n\n<a name=\"async-patterns.Promisify\"></a>\n\n### async-patterns.Promisify ⇒ <code>function</code>\n```javascript\n    const task = Promisify(\n        (onDone, i) => onDone(\n            i === 0 ? new Error('i cant be 0') : null,\n            i + 1\n        ),\n    );\n\n    const results = await task(1); // results is 2\n    const results2 = await taks(0); // throws 'i cant be 0 Error\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async function  \n**Params**\n\n- task <code>function</code> - a callback-expecting function\n\n\n* * *\n\n<a name=\"async-patterns.Race\"></a>\n\n### async-patterns.Race ⇒ <code>function</code>\n```javascript\n    const task = Race(\n        async (i) => i + 1,\n        async (i) => i + 2,\n    );\n\n    const result = await task(1); // 2\n```\n\n**Kind**: static property of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>function</code> - an async task that resolves or rejects as soon as the first one of its \"children\" resolves or rejects  \n**Params**\n\n- ...tasks <code>function</code> - any number of async tasks\n\n\n* * *\n\n<a name=\"async-patterns.testing\"></a>\n\n### async-patterns.testing : <code>object</code>\nA namespace.\n\n**Kind**: static namespace of [<code>async-patterns</code>](#async-patterns)  \n\n* [.testing](#async-patterns.testing) : <code>object</code>\n    * [.AssertionTest](#async-patterns.testing.AssertionTest)\n        * [new AssertionTest()](#new_async-patterns.testing.AssertionTest_new)\n        * [assertionTest.describe(description)](#async-patterns.testing.AssertionTest+describe) ⇒ <code>AssertionTest</code>\n        * [assertionTest.setup(task)](#async-patterns.testing.AssertionTest+setup) ⇒ <code>AssertionTest</code>\n        * [assertionTest.prepare(task)](#async-patterns.testing.AssertionTest+prepare) ⇒ <code>AssertionTest</code>\n        * [assertionTest.execute(task)](#async-patterns.testing.AssertionTest+execute) ⇒ <code>AssertionTest</code>\n        * [assertionTest.verify(...tasks)](#async-patterns.testing.AssertionTest+verify) ⇒ <code>AssertionTest</code>\n        * [assertionTest.teardown(task)](#async-patterns.testing.AssertionTest+teardown) ⇒ <code>AssertionTest</code>\n        * [assertionTest.build()](#async-patterns.testing.AssertionTest+build) ⇒ <code>function</code>\n        * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n        * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest\"></a>\n\n#### testing.AssertionTest\n**Kind**: static class of [<code>testing</code>](#async-patterns.testing)  \n\n* [.AssertionTest](#async-patterns.testing.AssertionTest)\n    * [new AssertionTest()](#new_async-patterns.testing.AssertionTest_new)\n    * [assertionTest.describe(description)](#async-patterns.testing.AssertionTest+describe) ⇒ <code>AssertionTest</code>\n    * [assertionTest.setup(task)](#async-patterns.testing.AssertionTest+setup) ⇒ <code>AssertionTest</code>\n    * [assertionTest.prepare(task)](#async-patterns.testing.AssertionTest+prepare) ⇒ <code>AssertionTest</code>\n    * [assertionTest.execute(task)](#async-patterns.testing.AssertionTest+execute) ⇒ <code>AssertionTest</code>\n    * [assertionTest.verify(...tasks)](#async-patterns.testing.AssertionTest+verify) ⇒ <code>AssertionTest</code>\n    * [assertionTest.teardown(task)](#async-patterns.testing.AssertionTest+teardown) ⇒ <code>AssertionTest</code>\n    * [assertionTest.build()](#async-patterns.testing.AssertionTest+build) ⇒ <code>function</code>\n    * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n    * [AssertionTest.VerifyErrorWasNotThrown()](#async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown)\n\n\n* * *\n\n<a name=\"new_async-patterns.testing.AssertionTest_new\"></a>\n\n##### new AssertionTest()\n```javascript\n\nconst PingTest = AssertionTest()\n  .describe('can ping internet')\n  .setup(\n    // build our setup\n    (next) => {\n      const setup = {};\n      setup.testHosts = [ 'google.com', 'microsoft.com', 'yahoo.com' ];\n      next(null, setup);\n    }\n  )\n  .prepare(\n    // run test with first host\n    (next, setup) => {\n      const host = setup.testHosts[0];\n      next(null, host);\n    }\n  )\n  .execute(\n    (next, host) => ping.sys.probe(\n      host,\n      (isAlive, error) => next(error, isAlive)\n    )\n  )\n  .verify(\n    // verify no error was thrown\n    (next, { setup, request, result, error }) => next(error),\n    // verify result is true\n    (next, { setup, request, result, error }) => next(\n      result !== true ? new Error(`could not ping host ${request}`) : null\n    )\n  )\n  .teardown(\n    // nothing to teardown\n    (next, { setup, request, result, error }) => next()\n  )\n  .build();\n\n  test( () => console.log('test done') );\n\n```\nConstructor for an AssertionTest builder.\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+describe\"></a>\n\n##### assertionTest.describe(description) ⇒ <code>AssertionTest</code>\n`AssertionTest#describe` lets you set a description for a test case.\nThis description is part of the label attached to the test case when built.\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- description <code>string</code> - a string label describing the test case\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+setup\"></a>\n\n##### assertionTest.setup(task) ⇒ <code>AssertionTest</code>\n`AssertionTest#setup` gives you a hook to build test fixtures before execution.\nThis is the first step that runs in a test.\n`setup` is a separate step from `prepare` because you often want to use\na common setup function to build test fixtures for multiple tests.\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- task <code>function</code> - a setup task function - should return a setup object\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+prepare\"></a>\n\n##### assertionTest.prepare(task) ⇒ <code>AssertionTest</code>\n`AssertionTest#prepare` gives you a hook to prepare the request that the test uses to execute.\nThis is the second step that runs in a test, and the last step before `execute`.\nThe `prepare` task is passed the results from `setup`.\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- task <code>function</code> - a prepare task function - should accept a context containing the setup, and return a request object to be given to the executing task\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+execute\"></a>\n\n##### assertionTest.execute(task) ⇒ <code>AssertionTest</code>\n`AssertionTest#execute` lets you specify the task that is executed in a test.\nThe `execute` task is passed the results from `prepare`.\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- task <code>function</code> - the task the test should execute, and capture results and errors from\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+verify\"></a>\n\n##### assertionTest.verify(...tasks) ⇒ <code>AssertionTest</code>\n`AssertionTest#verify` lets you specify any number of tasks to verify the test results.\nEach `verify` task is passed a complete record of all test fixtures in an object,\nincluding the setup, the request, the result, and the error (if an error was thrown)\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- ...tasks <code>function</code> - any number of verification tasks\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+teardown\"></a>\n\n##### assertionTest.teardown(task) ⇒ <code>AssertionTest</code>\n`AssertionTest#teardown` gives you a hook to tear down the test fixtures after execution.\nThe `teardown` task is passed a complete record of all test fixtures in an object,\nincluding the setup, the request, the result, and the error (if an error was thrown)\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>AssertionTest</code> - this  \n**Params**\n\n- task <code>function</code> - a task to tear down the setup\n\n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest+build\"></a>\n\n##### assertionTest.build() ⇒ <code>function</code>\nBuilds the test case function.\n\n**Kind**: instance method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n**Returns**: <code>function</code> - callback-expecting test function  \n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown\"></a>\n\n##### AssertionTest.VerifyErrorWasNotThrown()\nverifier function to make sure test DID NOT throw an error\n\n**Kind**: static method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n\n* * *\n\n<a name=\"async-patterns.testing.AssertionTest.VerifyErrorWasNotThrown\"></a>\n\n##### AssertionTest.VerifyErrorWasNotThrown()\nverifier function to make sure test DID throw an error\n\n**Kind**: static method of [<code>AssertionTest</code>](#async-patterns.testing.AssertionTest)  \n\n* * *\n\n<a name=\"async-patterns.unstable\"></a>\n\n### async-patterns.unstable : <code>object</code>\nA namespace.\n\n**Kind**: static namespace of [<code>async-patterns</code>](#async-patterns)  \n\n* * *\n\n<a name=\"async-patterns.unstable.TraceError\"></a>\n\n#### unstable.TraceError(task) ⇒ <code>function</code>\nTraceError is an experimental wrapper that attempts to make errors more informative.\nIt does this by appending extra information to the stack of any error thrown in the task.\n\nNOTE: TraceError is marked as 'unstable' as stack traces in JS are not standardized,\nso it may not always provide useful information.\n\n**Kind**: static method of [<code>unstable</code>](#async-patterns.unstable)  \n**Returns**: <code>function</code> - a wrapper function that modifies the stack trace of any errors thrown within  \n**Params**\n\n- task <code>function</code> - a task function to wrap\n\n\n* * *\n\n<a name=\"async-patterns.Assert\"></a>\n\n### async-patterns.Assert(validator, message) ⇒ <code>taskFunction</code>\n```javascript\n  let Assert = require('async-patterns/Assert');\n  let InSeries = require('async-patterns/InSeries');\n\n  let task = InSeries(\n    (num) => num,\n    Assert(\n      (num) => (num >= 0),\n      (num) => `${num} is less than zero`\n    ),\n    (num) => num,\n  );\n\n  await task(1); // returns 1\n\n  await task(-1); // throws error\n\n```\nBuilds an async assertion task.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - an assertion task  \n**Params**\n\n- validator <code>function</code> - a function that checks the arguments.\n- message <code>string</code> - an optional error message to throw if the assertion fails, or a message builder function.\n\n\n* * *\n\n<a name=\"async-patterns.Delay\"></a>\n\n### async-patterns.Delay(delay) ⇒ <code>taskFunction</code>\n```javascript\n  let Delay = require('async-patterns/Delay');\n  let InSeries = require('async-patterns/InSeries');\n\n  let task = InSeries(\n    (num) => num + 1\n    Delay(100),\n  );\n\n  await task(1); // returns 2, after a 100ms delay\n\n```\nDelay acts like PassThrough, but inserts a delay in the call.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a delay task  \n**Params**\n\n- delay <code>number</code> - The time to delay, in ms.\n\n\n* * *\n\n<a name=\"async-patterns.If\"></a>\n\n### async-patterns.If(ifTask, thenTask, elseTask) ⇒ <code>taskFunction</code>\n```javascript\n  let If = require('async-patterns/If');\n\n  let logIfEven = If(\n    (num) => (num % 2 === 0),\n    (num) => { console.log('is even!'); },\n    (num) => { console.log('is not even!'); }\n  );\n\n  await logIfEven(1); // prints out 'is not even!' eventually\n  await logIfEven(2); // prints out 'is even!' eventually\n\n```\nIf accepts up to three tasks,\nan 'if' task, a 'then' task, and lastly an 'else' task\nnote: by default, the ifTask, thenTask, and elseTask are PassThrough\nnote: the ifTask can return multiple results,\nbut only the first is checked for truthiness\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Params**\n\n- ifTask <code>taskFunction</code> - a condition task.\n- thenTask <code>taskFunction</code> - a task to run when ifTask returns a truthy value.\n- elseTask <code>taskFunction</code> - a task to run when ifTask returns a falsy value.\n\n\n* * *\n\n<a name=\"async-patterns.Logging\"></a>\n\n### async-patterns.Logging(...statements) ⇒ <code>taskFunction</code>\nA logging utility.\nIt passes the arguments received into all the statements, collects the results, and joins them together with newlines to build the final log statement\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a logging task  \n**Params**\n\n- ...statements <code>function</code> - any number of logging values.  Functions are called with the calling arguments, everything else is passed directly to\n\n\n* * *\n\n<a name=\"async-patterns.Memoize\"></a>\n\n### async-patterns.Memoize(task, [keyFunction]) ⇒ <code>AsyncTask</code>\nMemoize builds a wrapper function that caches results of previous executions.\nAs a result, repeated calls to Memoize may be much faster, if the request hits the cache.\n\nNOTE: As of now, there are no cache eviction mechanisms.\n  You should try to use Memoized functions in a 'disposable' way as a result\n\nNOTE: Memoize is not 'thread-safe' currently.  If two calls are made for the same object currently,\n  two calls to the wrapped function will be made\n\nNOTE: Memoize will cache errors as well as results.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Params**\n\n- task <code>AsyncTask</code> - the task function to memoize.\n- [keyFunction] <code>function</code> - a function that synchronously generates a key for a request.\n\n\n* * *\n\n<a name=\"async-patterns.Retry\"></a>\n\n### async-patterns.Retry(task, options) ⇒ <code>taskFunction</code>\nWraps a task and attempts to retry if it throws an error, with an exponential backoff.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a task  \n**Params**\n\n- task <code>taskFunction</code> - the task to wrap.\n- options <code>object</code> - an optional set of retry options.\n    - .timeout <code>object</code> - maximum time to attempt retries.\n    - .retries <code>object</code> - maximum number of retries to attempt.\n\n\n* * *\n\n<a name=\"async-patterns.Throttle\"></a>\n\n### async-patterns.Throttle(task, limit) ⇒ <code>taskFunction</code>\nWraps a task and ensures that only X number of instances of the task can be run in parallel.\nRequests are queued up in an unbounded FIFO queue until they can be run.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a task  \n**Params**\n\n- task <code>taskFunction</code> - the task to throttle\n- limit <code>number</code> - the number of instances that can run in parallel. default 1.\n\n\n* * *\n\n<a name=\"async-patterns.TimeIn\"></a>\n\n### async-patterns.TimeIn(task, ms) ⇒ <code>taskFunction</code>\n```javascript\n\n  let TimeIn = require('async-patterns/TimeIn');\n\n  let task = TimeIn(\n    async function (...args) {},\n\t\t\t1000\n  );\n\n  await task(...args);\n\n```\n\nTimeIn wraps a single task function, and returns a function that only returns after X ms.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a task  \n**Params**\n\n- task <code>taskFunction</code> - the task to wrap in a timeout.\n- ms <code>number</code> - the timein in ms.\n\n\n* * *\n\n<a name=\"async-patterns.TimeOut\"></a>\n\n### async-patterns.TimeOut(task, ms) ⇒ <code>taskFunction</code>\n```javascript\n\n  let TimeOut = require('async-patterns/TimeOut');\n\n  let task = TimeOut(\n    async function (...args) {},\n\t\t\t1000\n  );\n\n  await task(...args);\n\n```\n\nTimeOut wraps a single task function, and returns a function that returns early if the task fails to complete before the timeout triggers.\n\nNOTE: the timeout being triggered will not cancel the original task.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a task  \n**Params**\n\n- task <code>taskFunction</code> - the task to wrap in a timeout.\n- ms <code>number</code> - the timeout in ms.\n\n\n* * *\n\n<a name=\"async-patterns.Timer\"></a>\n\n### async-patterns.Timer(task, label) ⇒ <code>taskFunction</code>\nWraps a task and logs how long it takes to finish, or fail.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Returns**: <code>taskFunction</code> - a task  \n**Params**\n\n- task <code>taskFunction</code> - the task to wrap.\n- label <code>string</code> - an optional label to log.\n\n\n* * *\n\n<a name=\"async-patterns.While\"></a>\n\n### async-patterns.While(conditionTask, loopTask) ⇒ <code>function</code>\n```javascript\n\nlet While = require('async-patterns/While');\n\nlet task = While(\n  (num) => (num < 10),\n  (num) => num + 1\n);\n\nawait task(1); // prints 10, eventually\n\n```\nWhile accepts two tasks and returns a task that conditionally executes some number of times.\n\n**Kind**: static method of [<code>async-patterns</code>](#async-patterns)  \n**Params**\n\n- conditionTask <code>function</code> - a condition task.\n- loopTask <code>function</code> - a task to run if the condition returns a truthy value.\n\n\n* * *\n\n"
}