summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Robb <softnfuzzyrobb@gmail.com>2016-04-06 01:03:07 +0100
committerSteve Robb <softnfuzzyrobb@gmail.com>2016-04-06 01:03:07 +0100
commit8190a16caf58847495d33d5399e2a3c98cebd634 (patch)
tree60321a06c1b550ea86a2e202b347f71f1f4d097a
parent20c0a9be73f517fcb7cda940675007416bb3aa0c (diff)
parent5d2f19b360b7ec74db659ae571d730c1acc58b76 (diff)
downloadasync-8190a16caf58847495d33d5399e2a3c98cebd634.tar.gz
Merge branch 'master' into autoInjectPR
-rw-r--r--CHANGELOG.md68
-rw-r--r--Makefile6
-rw-r--r--README.md460
-rw-r--r--component.json2
-rw-r--r--dist/async.js6211
-rw-r--r--dist/async.min.js2
-rw-r--r--dist/async.min.map2
-rw-r--r--gulpfile.js89
-rw-r--r--lib/asyncify.js5
-rw-r--r--lib/auto.js170
-rw-r--r--lib/autoInject.js46
-rw-r--r--lib/constant.js7
-rw-r--r--lib/doDuring.js4
-rw-r--r--lib/doUntil.js4
-rw-r--r--lib/doWhilst.js4
-rw-r--r--lib/during.js4
-rw-r--r--lib/eachLimit.js4
-rw-r--r--lib/eachOfLimit.js4
-rw-r--r--lib/ensureAsync.js6
-rw-r--r--lib/everySeries.js6
-rw-r--r--lib/index.js28
-rw-r--r--lib/internal/applyEach.js4
-rw-r--r--lib/internal/createTester.js21
-rw-r--r--lib/internal/doLimit.js4
-rw-r--r--lib/internal/doParallel.js4
-rw-r--r--lib/internal/doParallelLimit.js4
-rw-r--r--lib/internal/doSeries.js4
-rw-r--r--lib/internal/eachOfLimit.js14
-rw-r--r--lib/internal/filter.js4
-rw-r--r--lib/internal/getIterator.js5
-rw-r--r--lib/internal/initialParams.js8
-rw-r--r--lib/internal/iterator.js36
-rw-r--r--lib/internal/keyIterator.js23
-rw-r--r--lib/internal/map.js9
-rw-r--r--lib/internal/once.js7
-rw-r--r--lib/internal/queue.js19
-rw-r--r--lib/internal/reject.js4
-rw-r--r--lib/internal/setImmediate.js18
-rw-r--r--lib/internal/withoutIndex.js4
-rw-r--r--lib/memoize.js9
-rw-r--r--lib/nextTick.js4
-rw-r--r--lib/race.js9
-rw-r--r--lib/reduce.js4
-rw-r--r--lib/reduceRight.js4
-rw-r--r--lib/reflect.js26
-rw-r--r--lib/reflectAll.js7
-rw-r--r--lib/retry.js90
-rw-r--r--lib/retryable.js18
-rw-r--r--lib/someSeries.js6
-rw-r--r--lib/sortBy.js4
-rw-r--r--lib/timeout.js29
-rw-r--r--lib/timesLimit.js4
-rw-r--r--lib/transform.js8
-rw-r--r--lib/until.js4
-rw-r--r--lib/waterfall.js35
-rw-r--r--lib/whilst.js6
-rw-r--r--mocha_test/auto.js57
-rw-r--r--mocha_test/autoInject.js77
-rw-r--r--mocha_test/cargo.js264
-rw-r--r--mocha_test/constant.js28
-rw-r--r--mocha_test/detect.js56
-rw-r--r--mocha_test/every.js13
-rw-r--r--mocha_test/filter.js12
-rw-r--r--mocha_test/nextTick.js38
-rw-r--r--mocha_test/priorityQueue.js123
-rw-r--r--mocha_test/queue.js614
-rw-r--r--mocha_test/retry.js101
-rw-r--r--mocha_test/retryable.js66
-rw-r--r--mocha_test/setImmediate.js24
-rw-r--r--mocha_test/some.js27
-rw-r--r--mocha_test/timeout.js48
-rw-r--r--mocha_test/waterfall.js148
-rw-r--r--package.json13
-rw-r--r--support/build.test.js4
-rwxr-xr-xsupport/xyz.sh6
-rwxr-xr-xtest/test-async.js1755
76 files changed, 6730 insertions, 4335 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3dc4946..1ac1ec9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,57 @@
+# v2.0.0
+
+Lots of changes here! The biggest feature is modularization. You can now `require("async/series")` to only require the `series` function. Every Async library function is available this way. You still can `require("async")` to require the entire library, like you could do before.
+
+We also provide Async as a collection of ES2015 modules. You can now `import {each} from 'async-es'` or `import waterfall from 'async-es/waterfall'`. If you are using only a few Async functions, and are using a ES bundler such as Rollup, this can significantly lower your build size.
+
+Major thanks to [**@Kikobeats**](github.com/Kikobeats), [**@aearly**](github.com/aearly) and [**@megawac**](github.com/megawac) for doing the majority of the modularization work, as well as [**@jdalton**](github.com/jdalton) and [**@Rich-Harris**](github.com/Rich-Harris) for advisory work on the general modularization strategy.
+
+Another one of the general themes of the 2.0 release is standardization of what an "async" function is. We are now more strictly following the node-style continuation passing style. That is, an async function is a function that:
+
+1. Takes a variable number of arguments
+2. The last argument is always a callback
+3. The callback can accept any number of arguments
+4. The first argument passed to the callback will be treated as an error result, if the argument is truthy
+5. Any number of result arguments can be passed after the "error" argument
+6. The callback is called once and exactly once, either on the same tick or later tick of the JavaScript event loop.
+
+There were several cases where Async accepted some functions that did not strictly have these properties, most notably `auto`, `every`, `some`, and `filter`.
+
+Another theme is performance. We have eliminated internal deferrals in all cases where they make sense. For example, in `waterfall` and `auto`, there was a `setImmediate` between each task -- these deferrals have been removed. A `setImmediate` call can add up to 1ms of delay. This might not seem like a lot, but it can add up if you are using many Async functions in the course of processing a HTTP request, for example. Nearly all asynchronous functions that do I/O already have some sort of deferral built in, so the extra deferral is unnecessary. The trade-off of this change is removing our built-in stack-overflow defense. Many synchronous callback calls in series can quickly overflow the JS call stack. If you do have a function that is sometimes synchronous (calling its callback on the same tick), and are running into stack overflows, wrap it with `async.ensureAsync()`.
+
+## New Features
+
+- Async is now modularized. Individual functions can be `require()`d from the main package. (`require('async/auto')`) (#984, #996)
+- Async is also available as a collection of ES2015 modules in the new `async-es` package. (`import {forEachSeries} from 'async-es'`) (#984, #996)
+- Added `race`, analogous to `Promise.race()`. It will run an array of async tasks in parallel and will call its callback with the result of the first task to respond. (#568, #1038)
+- Collection methods now accept ES2015 iterators. Maps, Sets, and anything that implements the iterator spec can now be passed directly to `each`, `map`, `parallel`, etc.. (#579, #839, #1074)
+- Added `timeout`, a wrapper for an async function that will make the task time-out after the specified time. (#1007, #1027)
+- Added `reflect` and `reflectAll`, analagous to [`Promise.reflect()`](http://bluebirdjs.com/docs/api/reflect.html), a wrapper for async tasks that always succeeds, by gathering results and errors into an object. (#942, #1012, #1095)
+- `constant` supports dynamic arguments -- it will now always use its last argument as the callback. (#1016, #1052)
+- `setImmediate` and `nextTick` now support arguments to partially apply to the deferred function, like the node-native versions do. (#940, #1053)
+- Added `autoInject`, a relative of `auto` that automatically spreads a task's dependencies as arguments to the task function. (#608, #1055)
+- You can now limit the concurrency of `auto` tasks. (#635, #637)
+- Added `retryable`, a relative of `retry` that wraps an async function, making it retry when called. (#1058)
+- Added `q.unsaturated` -- callback called when a `queue`'s number of running workers falls below a threshold. (#868, #1030, #1033, #1034)
+
+## Breaking changes
+
+- Calling a callback more than once is considered an error, and an error will be thrown. This had an explicit breaking change in `waterfall`. If you were relying on this behavior, you should more accurately represent your control flow as an event emitter or stream. (#814, #815, #1048, #1050)
+- `auto` task functions now always take the callback as the last argument. If a task has dependencies, the `results` object will be passed as the first argument. To migrate old task functions, wrap them with [`_.flip`](https://lodash.com/docs#flip) (#1036, #1042)
+- Internal `setImmediate` calls have been refactored away. This may make existing flows vulnerable to stack overflows if you use many synchronous functions in series. Use `ensureAsync` to work around this. (#696, #704, #1049, #1050)
+- `filter`, `reject`, `some`, `every`, and related functions now expect an error as the first callback argument, rather than just a simple boolean. Pass `null` as the first argument, or use `fs.access` instead of `fs.exists`. (#118, #774, #1028, #1041)
+- `{METHOD}` and `{METHOD}Series` are now implemented in terms of `{METHOD}Limit`. This is a major internal simplification, and is not expected to cause many problems, but it does subtly affect how functions execute internally. (#778, #847)
+- `retry`'s callback is now optional. Previously, omitting the callback would partially apply the function, meaning it could be passed directly as a task to `series` or `auto`. The partially applied "control-flow" behavior has been separated out into `retryable`. (#1054, #1058)
+- The timing of the `q.saturated()` callback in a `queue` has been modified to better reflect when tasks pushed to the queue will start queueing. (#724, #1078)
+
+## Other
+
+- Added `someSeries` and `everySeries` for symmetry, as well as a complete set of `any`/`anyLimit`/`anySeries` and `all`/`/allLmit`/`allSeries` aliases.
+- Added `find` as an alias for `detect. (as well as `findLimit` and `findSeries`).
+- Various doc fixes (#1005, #1008, #1010, #1015, #1021, #1037)
+
+------------------------------------------
+
# v1.5.2
- Allow using `"constructor"` as an argument in `memoize` (#998)
- Give a better error messsage when `auto` dependency checking fails (#994)
@@ -7,15 +61,15 @@
- Fix issue with `pause` in `queue` with concurrency enabled (#946)
- `while` and `until` now pass the final result to callback (#963)
- `auto` will properly handle concurrency when there is no callback (#966)
-- `auto` will now properly stop execution when an error occurs (#988, #993)
+- `auto` will no. properly stop execution when an error occurs (#988, #993)
- Various doc fixes (#971, #980)
# v1.5.0
- Added `transform`, analogous to [`_.transform`](http://lodash.com/docs#transform) (#892)
- `map` now returns an object when an object is passed in, rather than array with non-numeric keys. `map` will begin always returning an array with numeric indexes in the next major release. (#873)
-- `auto` now accepts an optional `concurrency` argument to limit the number of running tasks (#637)
-- Added `queue#workersList()`, to retrieve the list of currently running tasks. (#891)
+- `auto` now accepts an optional `concurrency` argument to limit the number o. running tasks (#637)
+- Added `queue#workersList()`, to retrieve the lis. of currently running tasks. (#891)
- Various code simplifications (#896, #904)
- Various doc fixes :scroll: (#890, #894, #903, #905, #912)
@@ -61,7 +115,7 @@ Bug Fixes:
Bug Fix:
-- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
+- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
# v1.2.0
@@ -69,7 +123,7 @@ Bug Fix:
New Features:
- Added `timesLimit` (#743)
-- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. (#747, #772)
+- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. (#747, #772)
Bug Fixes:
@@ -80,7 +134,7 @@ Bug Fixes:
Bug Fix:
-- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
+- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
# v1.1.0
@@ -92,7 +146,7 @@ New Features:
- Optimized `map`, `eachOf`, and `waterfall` families of functions
- Passing a `null` or `undefined` array to `map`, `each`, `parallel` and families will be treated as an empty array (#667).
- The callback is now optional for the composed results of `compose` and `seq`. (#618)
-- Reduced file size by 4kb, (minified version by 1kb)
+- Reduced file size by 4kb, (minified version by 1kb)
- Added code coverage through `nyc` and `coveralls` (#768)
Bug Fixes:
diff --git a/Makefile b/Makefile
index 80e8f52..dd61d50 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ DIST = dist
SRC = lib/index.js
SCRIPTS = ./support
JS_SRC = $(shell find lib/ -type f -name '*.js')
-LINT_FILES = lib/ test/ mocha_test/ $(shell find perf/ -maxdepth 2 -type f) support/ gulpfile.js karma.conf.js
+LINT_FILES = lib/ test/ mocha_test/ $(shell find perf/ -maxdepth 2 -type f) support/ karma.conf.js
UMD_BUNDLE = $(BUILDDIR)/dist/async.js
UMD_BUNDLE_MIN = $(BUILDDIR)/dist/async.min.js
@@ -111,8 +111,8 @@ build: clean build-bundle build-dist build-es build-config build-es-config test-
.PHONY: test lint build all clean
-.PHONY: release-major release-minor release-patch
-release-major release-minor release-patch: all
+.PHONY: release-major release-minor release-patch release-prerelease
+release-major release-minor release-patch release-prerelease: all
git add --force $(DIST)
git commit -am "update minified build"; true
$(XYZ) --increment $(@:release-%=%)
diff --git a/README.md b/README.md
index 562a27b..6a8ef52 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,15 @@
-NOTE: This is the README for Async 2.0, currently under development. There are some differences with the current stable version. For docs for async@1.5.2 go [HERE](https://github.com/caolan/async/blob/v1.5.2/README.md).
--------------------------
-
-# Async.js v2.0.0-pre
+# Async.js
[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
[![NPM version](http://img.shields.io/npm/v/async.svg)](https://www.npmjs.org/package/async)
[![Coverage Status](https://coveralls.io/repos/caolan/async/badge.svg?branch=master)](https://coveralls.io/r/caolan/async?branch=master)
[![Join the chat at https://gitter.im/caolan/async](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/caolan/async?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+*For Async v1.5.x documentation, go [HERE](https://github.com/caolan/async/blob/v1.5.2/README.md)*
Async is a utility module which provides straight-forward, powerful functions
for working with asynchronous JavaScript. Although originally designed for
-use with [Node.js](http://nodejs.org) and installable via `npm install async`,
+use with [Node.js](http://nodejs.org) and installable via `npm install --save async`,
it can also be used directly in the browser.
Async is also installable via:
@@ -21,11 +19,11 @@ Async is also installable via:
- [jam](http://jamjs.org/): `jam install async`
- [spm](http://spmjs.io/): `spm install async`
-Async provides around 20 functions that include the usual 'functional'
+Async provides around 70 functions that include the usual 'functional'
suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns
for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these
functions assume you follow the Node.js convention of providing a single
-callback as the last argument of your `async` function.
+callback as the last argument of your asynchronous function -- a callback which expects an Error as its first argument -- and calling the callback once.
## Quick Examples
@@ -39,7 +37,7 @@ async.filter(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
-}, function(results){
+}, function(err, results){
// results now equals an array of the existing files
});
@@ -87,10 +85,12 @@ async.eachSeries(hugeArray, function iteratee(item, callback) {
});
} else {
doSomeIO(item, callback);
- //...
+ //...
+ }
+});
```
-Async guards against synchronous functions in some, but not all, cases. If you are still running into stack overflows, you can defer as suggested above, or wrap functions with [`async.ensureAsync`](#ensureAsync) Functions that are asynchronous by their nature do not have this problem and don't need the extra callback deferral.
+Async does not guard against synchronous iteratees for performance reasons. If you are still running into stack overflows, you can defer as suggested above, or wrap functions with [`async.ensureAsync`](#ensureAsync) Functions that are asynchronous by their nature do not have this problem and don't need the extra callback deferral.
If JavaScript's event loop is still a bit nebulous, check out [this article](http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/) or [this talk](http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html) for more detailed information about how it works.
@@ -157,19 +157,32 @@ async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), fun
The source is available for download from
[GitHub](https://github.com/caolan/async/blob/master/lib/async.js).
-Alternatively, you can install using Node Package Manager (`npm`):
+Alternatively, you can install using npm:
- npm install async
+ npm install --save async
As well as using Bower:
bower install async
+You can then `require()` async as normal:
+
+```js
+var async = require("async");
+```
+
+Or require individual methods:
+
+```js
+var waterfall = require("async/waterfall");
+var map = require("async/map");
+```
+
__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed
-## In the Browser
+### In the Browser
-So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5.
+Async should work in any ES5 environment (IE9 and above).
Usage:
@@ -184,6 +197,17 @@ Usage:
</script>
```
+### ES Modules
+
+We also provide async as a collection of ES2015 modules, in an alternative `async-es` package on npm.
+
+ npm i -S async-es
+
+```js
+import waterfall from 'async-es/waterfall';
+import async from 'async-es';
+```
+
## Documentation
Some functions are also available in the following forms:
@@ -200,8 +224,8 @@ Some functions are also available in the following forms:
* [`reduce`](#reduce), [`reduceRight`](#reduceRight)
* [`detect`](#detect), `detectSeries`, `detectLimit`
* [`sortBy`](#sortBy)
-* [`some`](#some), `someLimit`
-* [`every`](#every), `everyLimit`
+* [`some`](#some), `someLimit`, `someSeries`
+* [`every`](#every), `everyLimit`, `everySeries`
* [`concat`](#concat), `concatSeries`
### Control Flow
@@ -221,6 +245,7 @@ Some functions are also available in the following forms:
* [`auto`](#auto)
* [`autoInject`](#autoInject)
* [`retry`](#retry)
+* [`retryable`](#retryable)
* [`iterator`](#iterator)
* [`times`](#times), `timesSeries`, `timesLimit`
* [`race`](#race)
@@ -238,14 +263,20 @@ Some functions are also available in the following forms:
* [`log`](#log)
* [`dir`](#dir)
* [`noConflict`](#noConflict)
+* [`timeout`](#timeout)
+* [`reflect`](#reflect)
+* [`reflectAll`](#reflectAll)
## Collections
+Collection methods can iterate over Arrays, Objects, Maps, Sets, and any object that implements the ES2015 iterator protocol.
+
<a name="forEach"></a>
<a name="each"></a>
-### each(arr, iteratee, [callback])
-Applies the function `iteratee` to each item in `arr`, in parallel.
+### each(coll, iteratee, [callback])
+
+Applies the function `iteratee` to each item in `coll`, in parallel.
The `iteratee` is called with an item from the list, and a callback for when it
has finished. If the `iteratee` passes an error to its `callback`, the main
`callback` (for the `each` function) is immediately called with the error.
@@ -255,8 +286,8 @@ there is no guarantee that the iteratee functions will complete in order.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A function to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A function to apply to each item in `coll`.
The iteratee is passed a `callback(err)` which must be called once it has
completed. If no error has occurred, the `callback` should be run without
arguments or with an explicit `null` argument. The array index is not passed
@@ -306,21 +337,22 @@ async.each(openFiles, function(file, callback) {
__Related__
-* eachSeries(arr, iteratee, [callback])
-* eachLimit(arr, limit, iteratee, [callback])
+* eachSeries(coll, iteratee, [callback])
+* eachLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="forEachOf"></a>
<a name="eachOf"></a>
-### forEachOf(obj, iteratee, [callback])
-Like `each`, except that it iterates over objects, and passes the key as the second argument to the iteratee.
+### forEachOf(coll, iteratee, [callback])
+
+Like `each`, except that it passes the key (or index) as the second argument to the iteratee.
__Arguments__
-* `obj` - An object or array to iterate over.
-* `iteratee(item, key, callback)` - A function to apply to each item in `obj`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, key, callback)` - A function to apply to each item in `coll`.
The `key` is the item's key, or index in the case of an array. The iteratee is
passed a `callback(err)` which must be called once it has completed. If no
error has occurred, the callback should be run without arguments or with an
@@ -352,33 +384,34 @@ async.forEachOf(obj, function (value, key, callback) {
__Related__
-* forEachOfSeries(obj, iteratee, [callback])
-* forEachOfLimit(obj, limit, iteratee, [callback])
+* forEachOfSeries(coll, iteratee, [callback])
+* forEachOfLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="map"></a>
-### map(arr, iteratee, [callback])
-Produces a new array of values by mapping each value in `arr` through
-the `iteratee` function. The `iteratee` is called with an item from `arr` and a
+### map(coll, iteratee, [callback])
+
+Produces a new collection of values by mapping each value in `coll` through
+the `iteratee` function. The `iteratee` is called with an item from `coll` and a
callback for when it has finished processing. Each of these callback takes 2 arguments:
-an `error`, and the transformed item from `arr`. If `iteratee` passes an error to its
+an `error`, and the transformed item from `coll`. If `iteratee` passes an error to its
callback, the main `callback` (for the `map` function) is immediately called with the error.
Note, that since this function applies the `iteratee` to each item in parallel,
there is no guarantee that the `iteratee` functions will complete in order.
-However, the results array will be in the same order as the original `arr`.
+However, the results array will be in the same order as the original `coll`.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A function to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A function to apply to each item in `coll`.
The iteratee is passed a `callback(err, transformed)` which must be called once
it has completed with an error (which can be `null`) and a transformed item.
* `callback(err, results)` - *Optional* A callback which is called when all `iteratee`
functions have finished, or an error occurs. Results is an array of the
- transformed items from the `arr`.
+ transformed items from the `coll`.
__Example__
@@ -390,25 +423,26 @@ async.map(['file1','file2','file3'], fs.stat, function(err, results){
__Related__
-* mapSeries(arr, iteratee, [callback])
-* mapLimit(arr, limit, iteratee, [callback])
+* mapSeries(coll, iteratee, [callback])
+* mapLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="select"></a>
<a name="filter"></a>
-### filter(arr, iteratee, [callback])
+
+### filter(coll, iteratee, [callback])
__Alias:__ `select`
-Returns a new array of all the values in `arr` which pass an async truth test.
+Returns a new array of all the values in `coll` which pass an async truth test.
This operation is performed in parallel,
but the results array will be in the same order as the original.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A truth test to apply to each item in `coll`.
The `iteratee` is passed a `callback(err, truthValue)`, which must be called with a
boolean argument once it has completed.
* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee`
@@ -421,36 +455,38 @@ async.filter(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
-}, function(results){
+}, function(err, results){
// results now equals an array of the existing files
});
```
__Related__
-* filterSeries(arr, iteratee, [callback])
-* filterLimit(arr, limit, iteratee, [callback])
+* filterSeries(coll, iteratee, [callback])
+* filterLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="reject"></a>
-### reject(arr, iteratee, [callback])
+
+### reject(coll, iteratee, [callback])
The opposite of [`filter`](#filter). Removes values that pass an `async` truth test.
__Related__
-* rejectSeries(arr, iteratee, [callback])
-* rejectLimit(arr, limit, iteratee, [callback])
+* rejectSeries(coll, iteratee, [callback])
+* rejectLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="reduce"></a>
-### reduce(arr, memo, iteratee, [callback])
+
+### reduce(coll, memo, iteratee, [callback])
__Aliases:__ `inject`, `foldl`
-Reduces `arr` into a single value using an async `iteratee` to return
+Reduces `coll` into a single value using an async `iteratee` to return
each successive step. `memo` is the initial state of the reduction.
This function only operates in series.
@@ -461,7 +497,7 @@ if you can get the data before reducing it, then it's probably a good idea to do
__Arguments__
-* `arr` - An array to iterate over.
+* `coll` - A collection to iterate over.
* `memo` - The initial state of the reduction.
* `iteratee(memo, item, callback)` - A function applied to each item in the
array to produce the next step in the reduction. The `iteratee` is passed a
@@ -488,28 +524,32 @@ async.reduce([1,2,3], 0, function(memo, item, callback){
---------------------------------------
<a name="reduceRight"></a>
-### reduceRight(arr, memo, iteratee, [callback])
+
+### reduceRight(coll, memo, iteratee, [callback])
__Alias:__ `foldr`
-Same as [`reduce`](#reduce), only operates on `arr` in reverse order.
+Same as [`reduce`](#reduce), only operates on `coll` in reverse order.
---------------------------------------
<a name="detect"></a>
-### detect(arr, iteratee, [callback])
-Returns the first value in `arr` that passes an async truth test. The
+### detect(coll, iteratee, [callback])
+
+__Alias:__ `find`
+
+Returns the first value in `coll` that passes an async truth test. The
`iteratee` is applied in parallel, meaning the first iteratee to return `true` will
fire the detect `callback` with that result. That means the result might not be
-the first item in the original `arr` (in terms of order) that passes the test.
+the first item in the original `coll` (in terms of order) that passes the test.
-If order within the original `arr` is important, then look at `detectSeries`.
+If order within the original `coll` is important, then look at `detectSeries`.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A truth test to apply to each item in `coll`.
The iteratee is passed a `callback(err, truthValue)` which must be called with a
boolean argument once it has completed.
* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
@@ -531,26 +571,27 @@ async.detect(['file1','file2','file3'], function(filePath, callback) {
__Related__
-* detectSeries(arr, iteratee, [callback])
-* detectLimit(arr, limit, iteratee, [callback])
+* detectSeries(coll, iteratee, [callback])
+* detectLimit(coll, limit, iteratee, [callback])
---------------------------------------
<a name="sortBy"></a>
-### sortBy(arr, iteratee, [callback])
-Sorts a list by the results of running each `arr` value through an async `iteratee`.
+### sortBy(coll, iteratee, [callback])
+
+Sorts a list by the results of running each `coll` value through an async `iteratee`.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A function to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A function to apply to each item in `coll`.
The iteratee is passed a `callback(err, sortValue)` which must be called once it
has completed with an error (which can be `null`) and a value to use as the sort
criteria.
* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee`
functions have finished, or an error occurs. Results is the items from
- the original `arr` sorted by the values returned by the `iteratee` calls.
+ the original `coll` sorted by the values returned by the `iteratee` calls.
__Example__
@@ -588,18 +629,19 @@ async.sortBy([1,9,3,5], function(x, callback){
---------------------------------------
<a name="some"></a>
-### some(arr, iteratee, [callback])
+
+### some(coll, iteratee, [callback])
__Alias:__ `any`
-Returns `true` if at least one element in the `arr` satisfies an async test.
+Returns `true` if at least one element in the `coll` satisfies an async test.
If any iteratee call returns `true`, the main `callback` is immediately called.
__Arguments__
-* `arr` - An array to iterate over.
+* `coll` - A collection to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in the array
- in parallel. The iteratee is passed a `callback(truthValue)`` which must be
+ in parallel. The iteratee is passed a `callback(err, truthValue)` which must be
called with a boolean argument once it has completed.
* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
`true`, or after all the iteratee functions have finished. Result will be
@@ -619,22 +661,24 @@ async.some(['file1','file2','file3'], function(filePath, callback) {
__Related__
-* someLimit(arr, limit, iteratee, callback)
+* someSeries(coll, iteratee, callback)
+* someLimit(coll, limit, iteratee, callback)
---------------------------------------
<a name="every"></a>
-### every(arr, iteratee, [callback])
+
+### every(coll, iteratee, [callback])
__Alias:__ `all`
-Returns `true` if every element in `arr` satisfies an async test.
+Returns `true` if every element in `coll` satisfies an async test.
If any iteratee call returns `false`, the main `callback` is immediately called.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A truth test to apply to each item in the array
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A truth test to apply to each item in the collection
in parallel. The iteratee is passed a `callback(err, truthValue)` which must be
called with a boolean argument once it has completed.
* `callback(err, result)` - *Optional* A callback which is called after all the `iteratee`
@@ -655,22 +699,24 @@ async.every(['file1','file2','file3'], function(filePath, callback) {
__Related__
-* everyLimit(arr, limit, iteratee, callback)
+* everySeries(coll, iteratee, callback)
+* everyLimit(coll, limit, iteratee, callback)
---------------------------------------
<a name="concat"></a>
-### concat(arr, iteratee, [callback])
-Applies `iteratee` to each item in `arr`, concatenating the results. Returns the
+### concat(coll, iteratee, [callback])
+
+Applies `iteratee` to each item in `coll`, concatenating the results. Returns the
concatenated list. The `iteratee`s are called in parallel, and the results are
concatenated as they return. There is no guarantee that the results array will
-be returned in the original order of `arr` passed to the `iteratee` function.
+be returned in the original order of `coll` passed to the `iteratee` function.
__Arguments__
-* `arr` - An array to iterate over.
-* `iteratee(item, callback)` - A function to apply to each item in `arr`.
+* `coll` - A collection to iterate over.
+* `iteratee(item, callback)` - A function to apply to each item in `coll`.
The iteratee is passed a `callback(err, results)` which must be called once it
has completed with an error (which can be `null`) and an array of results.
* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee`
@@ -687,15 +733,16 @@ async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
__Related__
-* concatSeries(arr, iteratee, [callback])
+* concatSeries(coll, iteratee, [callback])
## Control Flow
<a name="series"></a>
+
### series(tasks, [callback])
-Run the functions in the `tasks` array in series, each one running once the previous
+Run the functions in the `tasks` collection in series, each one running once the previous
function has completed. If any functions in the series pass an error to its
callback, no more functions are run, and `callback` is immediately called with the value of the error.
Otherwise, `callback` receives an array of results when `tasks` have completed.
@@ -716,7 +763,7 @@ this to work on all platforms, consider using an array.
__Arguments__
-* `tasks` - An array or object containing functions to run, each function is passed
+* `tasks` - A collection containing functions to run, each function is passed
a `callback(err, result)` it must call on completion with an error `err` (which can
be `null`) and an optional `result` value.
* `callback(err, results)` - An optional callback to run once all the functions
@@ -763,9 +810,10 @@ function(err, results) {
---------------------------------------
<a name="parallel"></a>
+
### parallel(tasks, [callback])
-Run the `tasks` array of functions in parallel, without waiting until the previous
+Run the `tasks` collection of functions in parallel, without waiting until the previous
function has completed. If any of the functions pass an error to its
callback, the main `callback` is immediately called with the value of the error.
Once the `tasks` have completed, the results are passed to the final `callback` as an
@@ -781,7 +829,7 @@ instead of an array. This can be a more readable way of handling results from
__Arguments__
-* `tasks` - An array or object containing functions to run. Each function is passed
+* `tasks` - A collection containing functions to run. Each function is passed
a `callback(err, result)` which it must call on completion with an error `err`
(which can be `null`) and an optional `result` value.
* `callback(err, results)` - An optional callback to run once all the functions
@@ -835,6 +883,7 @@ __Related__
---------------------------------------
<a name="whilst"></a>
+
### whilst(test, fn, callback)
Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,
@@ -872,6 +921,7 @@ async.whilst(
---------------------------------------
<a name="doWhilst"></a>
+
### doWhilst(fn, test, callback)
The post-check version of [`whilst`](#whilst). To reflect the difference in
@@ -882,6 +932,7 @@ the order of operations, the arguments `test` and `fn` are switched.
---------------------------------------
<a name="until"></a>
+
### until(test, fn, callback)
Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,
@@ -893,6 +944,7 @@ The inverse of [`whilst`](#whilst).
---------------------------------------
<a name="doUntil"></a>
+
### doUntil(fn, test, callback)
Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.
@@ -900,6 +952,7 @@ Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument o
---------------------------------------
<a name="during"></a>
+
### during(test, fn, callback)
Like [`whilst`](#whilst), except the `test` is an asynchronous function that is passed a callback in the form of `function (err, truth)`. If error is passed to `test` or `fn`, the main callback is immediately called with the value of the error.
@@ -926,6 +979,7 @@ async.during(
---------------------------------------
<a name="doDuring"></a>
+
### doDuring(fn, test, callback)
The post-check version of [`during`](#during). To reflect the difference in
@@ -936,6 +990,7 @@ Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function.
---------------------------------------
<a name="forever"></a>
+
### forever(fn, [errback])
Calls the asynchronous function `fn` with a callback parameter that allows it to
@@ -960,6 +1015,7 @@ async.forever(
---------------------------------------
<a name="waterfall"></a>
+
### waterfall(tasks, [callback])
Runs the `tasks` array of functions in series, each passing their results to the next in
@@ -1047,6 +1103,7 @@ function myLastFunction(arg1, callback) {
---------------------------------------
<a name="compose"></a>
+
### compose(fn1, fn2...)
Creates a function which is a composition of the passed asynchronous
@@ -1086,6 +1143,7 @@ add1mul3(4, function (err, result) {
---------------------------------------
<a name="seq"></a>
+
### seq(fn1, fn2...)
Version of the compose function that is more natural to read.
@@ -1127,6 +1185,7 @@ app.get('/cats', function(request, response) {
---------------------------------------
<a name="applyEach"></a>
+
### applyEach(fns, args..., callback)
Applies the provided arguments to each function in the array, calling
@@ -1162,6 +1221,7 @@ __Related__
---------------------------------------
<a name="queue"></a>
+
### queue(worker, [concurrency])
Creates a `queue` object with the specified `concurrency`. Tasks added to the
@@ -1194,8 +1254,8 @@ methods:
the `worker` has finished processing the task. Instead of a single task, a `tasks` array
can be submitted. The respective callback is used for every task in the list.
* `unshift(task, [callback])` - add a new task to the front of the `queue`.
-* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, and further tasks will be queued.
-* `unsaturated` - a callback that is called when the `queue` length is less than the `concurrency` & `buffer` limits, and further tasks will not be queued.
+* `saturated` - a callback that is called when the number of running workers hits the `concurrency` limit, and further tasks will be queued.
+* `unsaturated` - a callback that is called when the number of running workers is less than the `concurrency` & `buffer` limits, and further tasks will not be queued.
* `buffer` A minimum threshold buffer in order to say that the `queue` is `unsaturated`.
* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
@@ -1245,6 +1305,7 @@ q.unshift({name: 'bar'}, function (err) {
---------------------------------------
<a name="priorityQueue"></a>
+
### priorityQueue(worker, concurrency)
The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:
@@ -1256,6 +1317,7 @@ The same as [`queue`](#queue) only tasks are assigned a priority and completed i
---------------------------------------
<a name="cargo"></a>
+
### cargo(worker, [payload])
Creates a `cargo` object with the specified payload. Tasks added to the
@@ -1291,7 +1353,7 @@ methods:
* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.
* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.
* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.
-* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event calbacks as [`queue`](#queue)
+* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event callbacks as [`queue`](#queue)
__Example__
@@ -1322,6 +1384,7 @@ cargo.push({name: 'baz'}, function (err) {
---------------------------------------
<a name="auto"></a>
+
### auto(tasks, [concurrency], [callback])
Determines the best order for running the functions in `tasks`, based on their requirements. Each function can optionally depend on other functions being completed first, and each function is run as soon as its requirements are satisfied.
@@ -1421,6 +1484,73 @@ function(err, results){
For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding new tasks much easier (and the code more readable).
---------------------------------------
+<a name="autoInject" />
+### autoInject(tasks, [callback])
+
+A dependency-injected version of the [`auto`](#auto) function. Dependent tasks are specified as parameters to the function, after the usual callback parameter, with the parameter names matching the names of the tasks it depends on. This can provide even more readable task graphs which can be easier to maintain.
+
+If a final callback is specified, the task results are similarly injected, specified as named parameters after the initial error parameter.
+
+The autoInject function is purely syntactic sugar and its semantics are otherwise equivalent to [`auto`](#auto).
+
+__Arguments__
+
+* `tasks` - An object, each of whose properties is a function of the form
+ 'func([dependencies...], callback). The object's key of a property serves as the name of the task defined by that property, i.e. can be used when specifying requirements for other tasks.
+ * The `callback` parameter is a `callback(err, result)` which must be called when finished, passing an `error` (which can be `null`) and the result of the function's execution. The remaining parameters name other tasks on which the task is dependent, and the results from those tasks are the arguments of those parameters.
+* `callback(err, [results...])` - An optional callback which is called when all the tasks have been completed. It receives the `err` argument if any `tasks` pass an error to their callback. The remaining parameters are task names whose results you are interested in. This callback will only be called when all tasks have finished or an error has occurred, and so do not not specify dependencies in the same way as `tasks` do. If an error occurs, no further `tasks` will be performed, and `results` will only be valid for those tasks which managed to complete.
+
+
+__Example__
+
+The example from [`auto`](#auto) can be rewritten as follows:
+
+```js
+async.autoInject({
+ get_data: function(callback){
+ // async code to get some data
+ callback(null, 'data', 'converted to array');
+ },
+ make_folder: function(callback){
+ // async code to create a directory to store a file in
+ // this is run at the same time as getting the data
+ callback(null, 'folder');
+ },
+ write_file: function(get_data, make_folder, callback){
+ // once there is some data and the directory exists,
+ // write the data to a file in the directory
+ callback(null, 'filename');
+ },
+ email_link: function(write_file, callback){
+ // once the file is written let's email a link to it...
+ // write_file contains the filename returned by write_file.
+ callback(null, {'file':write_file, 'email':'user@example.com'});
+ }
+}, function(err, email_link) {
+ console.log('err = ', err);
+ console.log('email_link = ', email_link);
+});
+```
+
+If you are using a JS minifier that mangles parameter names, `autoInject` will not work with plain functions, since the parameter names will be collapsed to a single letter identifier. To work around this, you can explicitly specify the names of the parameters your task function needs in an array, similar to Angular.js dependency injection.
+
+```js
+async.autoInject({
+ //...
+ write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback){
+ callback(null, 'filename');
+ }],
+ email_link: ['write_file', function(write_file, callback){
+ callback(null, {'file':write_file, 'email':'user@example.com'});
+ }]
+ //...
+}, done);
+```
+
+This still has an advantage over plain `auto`, since the results a task depends on are still spread into arguments.
+
+
+---------------------------------------
<a name="autoInject"></a>
### autoInject(tasks, [callback])
@@ -1490,6 +1620,7 @@ async.autoInject({
---------------------------------------
<a name="retry"></a>
+
### retry([opts = {times: 5, interval: 0}| 5], task, [callback])
Attempts to get a successful response from `task` no more than `times` times before
@@ -1545,9 +1676,35 @@ async.auto({
});
```
+
+---------------------------------------
+
+<a name="retryable"></a>
+
+### retryable([opts = {times: 5, interval: 0}| 5], task)
+
+A close relative of `retry`. This method wraps a task and makes it retryable, rather than immediately calling it with retries.
+
+__Arguments__
+
+* `opts` - optional options, exactly the same as from `retry`
+* `task` - the asynchronous function to wrap
+
+__Example__
+
+```js
+async.auto({
+ dep1: async.retryable(3, getFromFlakyService),
+ process: ["dep1", async.retryable(3, function (results, cb) {
+ maybeProcessData(results.dep1, cb)
+ })]
+}, callback)
+```
+
---------------------------------------
<a name="iterator"></a>
+
### iterator(tasks)
Creates an iterator function which calls the next function in the `tasks` array,
@@ -1584,6 +1741,7 @@ node> nextfn();
## Utils
<a name="apply"></a>
+
### apply(function, arguments..)
Creates a continuation function with some arguments already applied.
@@ -1635,18 +1793,17 @@ three
---------------------------------------
<a name="nextTick"></a>
-### nextTick(callback), setImmediate(callback)
-Calls `callback` on a later loop around the event loop. In Node.js this just
-calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`
-if available, otherwise `setTimeout(callback, 0)`, which means other higher priority
-events may precede the execution of `callback`.
+### nextTick(callback, [args...]), setImmediate(callback, [args...])
+
+Calls `callback` on a later loop around the event loop. In Node.js this just calls `setImmediate`. In the browser it will use `setImmediate` if available, otherwise `setTimeout(callback, 0)`, which means other higher priority events may precede the execution of `callback`.
This is used internally for browser-compatibility purposes.
__Arguments__
* `callback` - The function to call on a later loop around the event loop.
+* `args...` - any number of additional arguments to pass to the callback on the next tick
__Example__
@@ -1657,11 +1814,16 @@ async.nextTick(function(){
// call_order now equals ['one','two']
});
call_order.push('one')
+
+async.setImmediate(function (a, b, c) {
+ // a, b, and c equal 1, 2, and 3
+}, 1, 2, 3)
```
---------------------------------------
<a name="times"></a>
+
### times(n, iteratee, [callback])
Calls the `iteratee` function `n` times, and accumulates results in the same manner
@@ -1740,6 +1902,7 @@ function(err, result){
---------------------------------------
<a name="memoize"></a>
+
### memoize(fn, [hasher])
Caches the results of an `async` function. When creating a hash to store function
@@ -1776,6 +1939,7 @@ fn('some name', function () {
---------------------------------------
<a name="unmemoize"></a>
+
### unmemoize(fn)
Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized
@@ -1788,6 +1952,7 @@ __Arguments__
---------------------------------------
<a name="ensureAsync"></a>
+
### ensureAsync(fn)
Wrap an async function and ensure it calls its callback on a later tick of the event loop. If the function already calls its callback on a next tick, no extra deferral is added. This is useful for preventing stack overflows (`RangeError: Maximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) contained.
@@ -1821,6 +1986,7 @@ async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
---------------------------------------
<a name="constant"></a>
+
### constant(values...)
Returns a function that when called, calls-back with the values provided. Useful as the first function in a `waterfall`, or for plugging values in to `auto`.
@@ -1860,6 +2026,7 @@ async.auto({
<a name="asyncify"></a>
<a name="wrapSync"></a>
+
### asyncify(func)
__Alias:__ `wrapSync`
@@ -1908,6 +2075,7 @@ q.push(files);
---------------------------------------
<a name="log"></a>
+
### log(function, arguments)
Logs the result of an `async` function to the `console`. Only works in Node.js or
@@ -1937,6 +2105,7 @@ node> async.log(hello, 'world');
---------------------------------------
<a name="dir"></a>
+
### dir(function, arguments)
Logs the result of an `async` function to the `console` using `console.dir` to
@@ -1967,7 +2136,110 @@ node> async.dir(hello, 'world');
---------------------------------------
<a name="noConflict"></a>
+
### noConflict()
Changes the value of `async` back to its original value, returning a reference to the
`async` object.
+
+---------------------------------------
+
+<a name="timeout"></a>
+
+### timeout(function, miliseconds)
+
+Sets a time limit on an asynchronous function. If the function does not call its callback within the specified miliseconds, it will be called with a timeout error. The code property for the error object will be `'ETIMEDOUT'`.
+
+Returns a wrapped function that can be used with any of the control flow functions.
+
+__Arguments__
+
+* `function` - The asynchronous function you want to set the time limit.
+* `miliseconds` - The specified time limit.
+
+__Example__
+
+```js
+async.timeout(function(callback) {
+ doAsyncTask(callback);
+}, 1000);
+```
+
+---------------------------------------
+
+<a name="reflect"></a>
+### reflect(function)
+
+Wraps the function in another function that always returns data even when it errors.
+The object returns ether has a property of error or value.
+
+__Arguments__
+
+* `function` - The function you want to wrap
+
+__Example__
+
+```js
+async.parallel([
+ async.reflect(function(callback){
+ // do some stuff ...
+ callback(null, 'one');
+ }),
+ async.reflect(function(callback){
+ // do some more stuff but error ...
+ callback('bad stuff happened');
+ }),
+ async.reflect(function(callback){
+ // do some more stuff ...
+ callback(null, 'two');
+ })
+],
+// optional callback
+function(err, results){
+ // values
+ // results[0].value = 'one'
+ // results[1].error = 'bad stuff happened'
+ // results[2].value = 'two'
+});
+```
+
+---------------------------------------
+
+<a name="reflectAll"></a>
+### reflectAll()
+
+A helper function that wraps an array of functions with reflect.
+
+__Arguments__
+
+* `tasks` - The array of functions to wrap in reflect.
+
+__Example__
+
+```javascript
+let tasks = [
+ function(callback){
+ setTimeout(function(){
+ callback(null, 'one');
+ }, 200);
+ },
+ function(callback){
+ // do some more stuff but error ...
+ callback(new Error('bad stuff happened'));
+ }
+ function(callback){
+ setTimeout(function(){
+ callback(null, 'two');
+ }, 100);
+ }
+];
+
+async.parallel(async.reflectAll(tasks),
+// optional callback
+function(err, results){
+ // values
+ // results[0].value = 'one'
+ // results[1].error = Error('bad stuff happened')
+ // results[2].value = 'two'
+});
+```
diff --git a/component.json b/component.json
index 2ce99fc..cf687d2 100644
--- a/component.json
+++ b/component.json
@@ -1,7 +1,7 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
- "version": "2.0.0-alpha",
+ "version": "2.0.0-rc.2",
"keywords": [
"async",
"callback",
diff --git a/dist/async.js b/dist/async.js
index 0032ce5..5aa8490 100644
--- a/dist/async.js
+++ b/dist/async.js
@@ -1,2563 +1,3924 @@
(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.async = {})));
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (factory((global.async = global.async || {})));
}(this, function (exports) { 'use strict';
- /**
- * A faster alternative to `Function#apply`, this function invokes `func`
- * with the `this` binding of `thisArg` and the arguments of `args`.
- *
- * @private
- * @param {Function} func The function to invoke.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {...*} args The arguments to invoke `func` with.
- * @returns {*} Returns the result of `func`.
- */
- function apply$1(func, thisArg, args) {
- var length = args.length;
- switch (length) {
- case 0: return func.call(thisArg);
- case 1: return func.call(thisArg, args[0]);
- case 2: return func.call(thisArg, args[0], args[1]);
- case 3: return func.call(thisArg, args[0], args[1], args[2]);
- }
- return func.apply(thisArg, args);
- }
-
- /**
- * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(_.noop);
- * // => true
- *
- * _.isObject(null);
- * // => false
- */
- function isObject(value) {
- var type = typeof value;
- return !!value && (type == 'object' || type == 'function');
- }
-
- var funcTag = '[object Function]';
- var genTag = '[object GeneratorFunction]';
- /** Used for built-in method references. */
- var objectProto$4 = Object.prototype;
-
- /**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objectToString$2 = objectProto$4.toString;
-
- /**
- * Checks if `value` is classified as a `Function` object.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- *
- * _.isFunction(/abc/);
- * // => false
- */
- function isFunction(value) {
- // The use of `Object#toString` avoids issues with the `typeof` operator
- // in Safari 8 which returns 'object' for typed array constructors, and
- // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
- var tag = isObject(value) ? objectToString$2.call(value) : '';
- return tag == funcTag || tag == genTag;
- }
-
- /** Used as references for various `Number` constants. */
- var NAN = 0 / 0;
-
- /** Used to match leading and trailing whitespace. */
- var reTrim = /^\s+|\s+$/g;
-
- /** Used to detect bad signed hexadecimal string values. */
- var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
-
- /** Used to detect binary string values. */
- var reIsBinary = /^0b[01]+$/i;
-
- /** Used to detect octal string values. */
- var reIsOctal = /^0o[0-7]+$/i;
-
- /** Built-in method references without a dependency on `root`. */
- var freeParseInt = parseInt;
-
- /**
- * Converts `value` to a number.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to process.
- * @returns {number} Returns the number.
- * @example
- *
- * _.toNumber(3);
- * // => 3
- *
- * _.toNumber(Number.MIN_VALUE);
- * // => 5e-324
- *
- * _.toNumber(Infinity);
- * // => Infinity
- *
- * _.toNumber('3');
- * // => 3
- */
- function toNumber(value) {
- if (isObject(value)) {
- var other = isFunction(value.valueOf) ? value.valueOf() : value;
- value = isObject(other) ? (other + '') : other;
- }
- if (typeof value != 'string') {
- return value === 0 ? value : +value;
- }
- value = value.replace(reTrim, '');
- var isBinary = reIsBinary.test(value);
- return (isBinary || reIsOctal.test(value))
- ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
- : (reIsBadHex.test(value) ? NAN : +value);
- }
-
- var INFINITY = 1 / 0;
- var MAX_INTEGER = 1.7976931348623157e+308;
- /**
- * Converts `value` to an integer.
- *
- * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {number} Returns the converted integer.
- * @example
- *
- * _.toInteger(3);
- * // => 3
- *
- * _.toInteger(Number.MIN_VALUE);
- * // => 0
- *
- * _.toInteger(Infinity);
- * // => 1.7976931348623157e+308
- *
- * _.toInteger('3');
- * // => 3
- */
- function toInteger(value) {
- if (!value) {
- return value === 0 ? value : 0;
- }
- value = toNumber(value);
- if (value === INFINITY || value === -INFINITY) {
- var sign = (value < 0 ? -1 : 1);
- return sign * MAX_INTEGER;
- }
- var remainder = value % 1;
- return value === value ? (remainder ? value - remainder : value) : 0;
- }
-
- /** Used as the `TypeError` message for "Functions" methods. */
- var FUNC_ERROR_TEXT = 'Expected a function';
-
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeMax = Math.max;
-
- /**
- * Creates a function that invokes `func` with the `this` binding of the
- * created function and arguments from `start` and beyond provided as an array.
- *
- * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var say = _.rest(function(what, names) {
- * return what + ' ' + _.initial(names).join(', ') +
- * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
- * });
- *
- * say('hello', 'fred', 'barney', 'pebbles');
- * // => 'hello fred, barney, & pebbles'
- */
- function rest(func, start) {
- if (typeof func != 'function') {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
- start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
- return function() {
- var args = arguments,
- index = -1,
- length = nativeMax(args.length - start, 0),
- array = Array(length);
-
- while (++index < length) {
- array[index] = args[start + index];
+ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply(func, thisArg, args) {
+ var length = args.length;
+ switch (length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
- switch (start) {
- case 0: return func.call(this, array);
- case 1: return func.call(this, args[0], array);
- case 2: return func.call(this, args[0], args[1], array);
+ return func.apply(thisArg, args);
+ }
+
+ /**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+ }
+
+ var funcTag = '[object Function]';
+ var genTag = '[object GeneratorFunction]';
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+ function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 8 which returns 'object' for typed array and weak map constructors,
+ // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
+ }
+
+ /** Used as references for various `Number` constants. */
+ var NAN = 0 / 0;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g;
+
+ /** Used to detect bad signed hexadecimal string values. */
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+ /** Used to detect binary string values. */
+ var reIsBinary = /^0b[01]+$/i;
+
+ /** Used to detect octal string values. */
+ var reIsOctal = /^0o[0-7]+$/i;
+
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseInt = parseInt;
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3);
+ * // => 3
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3');
+ * // => 3
+ */
+ function toNumber(value) {
+ if (isObject(value)) {
+ var other = isFunction(value.valueOf) ? value.valueOf() : value;
+ value = isObject(other) ? (other + '') : other;
}
- var otherArgs = Array(start + 1);
- index = -1;
- while (++index < start) {
- otherArgs[index] = args[index];
+ if (typeof value != 'string') {
+ return value === 0 ? value : +value;
}
- otherArgs[start] = array;
- return apply$1(func, this, otherArgs);
- };
- }
-
- function applyEach$1(eachfn) {
- return rest(function (fns, args) {
- var go = rest(function (args) {
- var that = this;
- var callback = args.pop();
- return eachfn(fns, function (fn, _, cb) {
- fn.apply(that, args.concat([cb]));
- }, callback);
- });
- if (args.length) {
- return go.apply(this, args);
- } else {
- return go;
- }
- });
- }
-
- /** Used as the `TypeError` message for "Functions" methods. */
- var FUNC_ERROR_TEXT$1 = 'Expected a function';
-
- /**
- * Creates a function that invokes `func`, with the `this` binding and arguments
- * of the created function, while it's called less than `n` times. Subsequent
- * calls to the created function return the result of the last `func` invocation.
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {number} n The number of calls at which `func` is no longer invoked.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * jQuery(element).on('click', _.before(5, addContactToList));
- * // => allows adding up to 4 contacts to the list
- */
- function before(n, func) {
- var result;
- if (typeof func != 'function') {
- throw new TypeError(FUNC_ERROR_TEXT$1);
- }
- n = toInteger(n);
- return function() {
- if (--n > 0) {
- result = func.apply(this, arguments);
+ value = value.replace(reTrim, '');
+ var isBinary = reIsBinary.test(value);
+ return (isBinary || reIsOctal.test(value))
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+ : (reIsBadHex.test(value) ? NAN : +value);
+ }
+
+ var INFINITY = 1 / 0;
+ var MAX_INTEGER = 1.7976931348623157e+308;
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3');
+ * // => 3
+ */
+ function toInteger(value) {
+ if (!value) {
+ return value === 0 ? value : 0;
}
- if (n <= 1) {
- func = undefined;
+ value = toNumber(value);
+ if (value === INFINITY || value === -INFINITY) {
+ var sign = (value < 0 ? -1 : 1);
+ return sign * MAX_INTEGER;
}
- return result;
- };
- }
-
- /**
- * Creates a function that is restricted to invoking `func` once. Repeat calls
- * to the function return the value of the first invocation. The `func` is
- * invoked with the `this` binding and arguments of the created function.
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` invokes `createApplication` once
- */
- function once(func) {
- return before(2, func);
- }
-
- /**
- * A no-operation function that returns `undefined` regardless of the
- * arguments it receives.
- *
- * @static
- * @memberOf _
- * @category Util
- * @example
- *
- * var object = { 'user': 'fred' };
- *
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // No operation performed.
- }
-
- /**
- * The base implementation of `_.property` without support for deep paths.
- *
- * @private
- * @param {string} key The key of the property to get.
- * @returns {Function} Returns the new function.
- */
- function baseProperty(key) {
- return function(object) {
- return object == null ? undefined : object[key];
- };
- }
-
- /**
- * Gets the "length" property value of `object`.
- *
- * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
- * that affects Safari on at least iOS 8.1-8.3 ARM64.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {*} Returns the "length" value.
- */
- var getLength = baseProperty('length');
-
- /** Used as references for various `Number` constants. */
- var MAX_SAFE_INTEGER$1 = 9007199254740991;
-
- /**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
- * @example
- *
- * _.isLength(3);
- * // => true
- *
- * _.isLength(Number.MIN_VALUE);
- * // => false
- *
- * _.isLength(Infinity);
- * // => false
- *
- * _.isLength('3');
- * // => false
- */
- function isLength(value) {
- return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
- }
-
- /**
- * Checks if `value` is array-like. A value is considered array-like if it's
- * not a function and has a `value.length` that's an integer greater than or
- * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
- * @example
- *
- * _.isArrayLike([1, 2, 3]);
- * // => true
- *
- * _.isArrayLike(document.body.children);
- * // => true
- *
- * _.isArrayLike('abc');
- * // => true
- *
- * _.isArrayLike(_.noop);
- * // => false
- */
- function isArrayLike(value) {
- return value != null &&
- !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
- }
-
- /** Used for built-in method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /** Built-in value references. */
- var getPrototypeOf = Object.getPrototypeOf;
-
- /**
- * The base implementation of `_.has` without support for deep paths.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} key The key to check.
- * @returns {boolean} Returns `true` if `key` exists, else `false`.
- */
- function baseHas(object, key) {
- // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
- // that are composed entirely of index properties, return `false` for
- // `hasOwnProperty` checks of them.
- return hasOwnProperty.call(object, key) ||
- (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
- }
-
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeKeys = Object.keys;
-
- /**
- * The base implementation of `_.keys` which doesn't skip the constructor
- * property of prototypes or treat sparse arrays as dense.
- *
- * @private
- * @type Function
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
- function baseKeys(object) {
- return nativeKeys(Object(object));
- }
-
- /**
- * The base implementation of `_.times` without support for iteratee shorthands
- * or max array length checks.
- *
- * @private
- * @param {number} n The number of times to invoke `iteratee`.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the array of results.
- */
- function baseTimes(n, iteratee) {
- var index = -1,
- result = Array(n);
-
- while (++index < n) {
- result[index] = iteratee(index);
- }
- return result;
- }
-
- /**
- * Checks if `value` is object-like. A value is object-like if it's not `null`
- * and has a `typeof` result of "object".
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
- * @example
- *
- * _.isObjectLike({});
- * // => true
- *
- * _.isObjectLike([1, 2, 3]);
- * // => true
- *
- * _.isObjectLike(_.noop);
- * // => false
- *
- * _.isObjectLike(null);
- * // => false
- */
- function isObjectLike(value) {
- return !!value && typeof value == 'object';
- }
-
- /**
- * This method is like `_.isArrayLike` except that it also checks if `value`
- * is an object.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
- * @example
- *
- * _.isArrayLikeObject([1, 2, 3]);
- * // => true
- *
- * _.isArrayLikeObject(document.body.children);
- * // => true
- *
- * _.isArrayLikeObject('abc');
- * // => false
- *
- * _.isArrayLikeObject(_.noop);
- * // => false
- */
- function isArrayLikeObject(value) {
- return isObjectLike(value) && isArrayLike(value);
- }
-
- /** `Object#toString` result references. */
- var argsTag = '[object Arguments]';
-
- /** Used for built-in method references. */
- var objectProto$2 = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
-
- /**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objectToString = objectProto$2.toString;
-
- /** Built-in value references. */
- var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
-
- /**
- * Checks if `value` is likely an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isArguments(function() { return arguments; }());
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
- return isArrayLikeObject(value) && hasOwnProperty$1.call(value, 'callee') &&
- (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
- }
-
- /**
- * Checks if `value` is classified as an `Array` object.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isArray([1, 2, 3]);
- * // => true
- *
- * _.isArray(document.body.children);
- * // => false
- *
- * _.isArray('abc');
- * // => false
- *
- * _.isArray(_.noop);
- * // => false
- */
- var isArray = Array.isArray;
-
- /** `Object#toString` result references. */
- var stringTag = '[object String]';
-
- /** Used for built-in method references. */
- var objectProto$3 = Object.prototype;
-
- /**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objectToString$1 = objectProto$3.toString;
-
- /**
- * Checks if `value` is classified as a `String` primitive or object.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isString('abc');
- * // => true
- *
- * _.isString(1);
- * // => false
- */
- function isString(value) {
- return typeof value == 'string' ||
- (!isArray(value) && isObjectLike(value) && objectToString$1.call(value) == stringTag);
- }
-
- /**
- * Creates an array of index keys for `object` values of arrays,
- * `arguments` objects, and strings, otherwise `null` is returned.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array|null} Returns index keys, else `null`.
- */
- function indexKeys(object) {
- var length = object ? object.length : undefined;
- if (isLength(length) &&
- (isArray(object) || isString(object) || isArguments(object))) {
- return baseTimes(length, String);
- }
- return null;
- }
-
- /** Used as references for various `Number` constants. */
- var MAX_SAFE_INTEGER = 9007199254740991;
-
- /** Used to detect unsigned integer values. */
- var reIsUint = /^(?:0|[1-9]\d*)$/;
-
- /**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
- function isIndex(value, length) {
- value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
- length = length == null ? MAX_SAFE_INTEGER : length;
- return value > -1 && value % 1 == 0 && value < length;
- }
-
- /** Used for built-in method references. */
- var objectProto$1 = Object.prototype;
-
- /**
- * Checks if `value` is likely a prototype object.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
- */
- function isPrototype(value) {
- var Ctor = value && value.constructor,
- proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$1;
-
- return value === proto;
- }
-
- /**
- * Creates an array of the own enumerable property names of `object`.
- *
- * **Note:** Non-object values are coerced to objects. See the
- * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
- * for more details.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.keys(new Foo);
- * // => ['a', 'b'] (iteration order is not guaranteed)
- *
- * _.keys('hi');
- * // => ['0', '1']
- */
- function keys(object) {
- var isProto = isPrototype(object);
- if (!(isProto || isArrayLike(object))) {
- return baseKeys(object);
- }
- var indexes = indexKeys(object),
- skipIndexes = !!indexes,
- result = indexes || [],
- length = result.length;
-
- for (var key in object) {
- if (baseHas(object, key) &&
- !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
- !(isProto && key == 'constructor')) {
- result.push(key);
+ var remainder = value % 1;
+ return value === value ? (remainder ? value - remainder : value) : 0;
+ }
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT = 'Expected a function';
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax = Math.max;
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.rest(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+ function rest(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
}
+ start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ array = Array(length);
+
+ while (++index < length) {
+ array[index] = args[start + index];
+ }
+ switch (start) {
+ case 0: return func.call(this, array);
+ case 1: return func.call(this, args[0], array);
+ case 2: return func.call(this, args[0], args[1], array);
+ }
+ var otherArgs = Array(start + 1);
+ index = -1;
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = array;
+ return apply(func, this, otherArgs);
+ };
}
- return result;
- }
-
- function keyIterator(coll) {
- var i = -1;
- var len;
- if (isArrayLike(coll)) {
- len = coll.length;
- return function next() {
- i++;
- return i < len ? i : null;
- };
- } else {
- var okeys = keys(coll);
- len = okeys.length;
- return function next() {
- i++;
- return i < len ? okeys[i] : null;
- };
+
+ function initialParams (fn) {
+ return rest(function (args /*..., callback*/) {
+ var callback = args.pop();
+ fn(args, callback);
+ });
+ }
+
+ function applyEach$1(eachfn) {
+ return rest(function (fns, args) {
+ var go = initialParams(function (args, callback) {
+ var that = this;
+ return eachfn(fns, function (fn, _, cb) {
+ fn.apply(that, args.concat([cb]));
+ }, callback);
+ });
+ if (args.length) {
+ return go.apply(this, args);
+ } else {
+ return go;
+ }
+ });
+ }
+
+ /**
+ * A no-operation function that returns `undefined` regardless of the
+ * arguments it receives.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.noop(object) === undefined;
+ * // => true
+ */
+ function noop() {
+ // No operation performed.
+ }
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT$1 = 'Expected a function';
+
+ /**
+ * Creates a function that invokes `func`, with the `this` binding and arguments
+ * of the created function, while it's called less than `n` times. Subsequent
+ * calls to the created function return the result of the last `func` invocation.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {number} n The number of calls at which `func` is no longer invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * jQuery(element).on('click', _.before(5, addContactToList));
+ * // => allows adding up to 4 contacts to the list
+ */
+ function before(n, func) {
+ var result;
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT$1);
}
- }
+ n = toInteger(n);
+ return function() {
+ if (--n > 0) {
+ result = func.apply(this, arguments);
+ }
+ if (n <= 1) {
+ func = undefined;
+ }
+ return result;
+ };
+ }
- function onlyOnce(fn) {
- return function () {
- if (fn === null) throw new Error("Callback was already called.");
- fn.apply(this, arguments);
- fn = null;
+ /**
+ * Creates a function that is restricted to invoking `func` once. Repeat calls
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var initialize = _.once(createApplication);
+ * initialize();
+ * initialize();
+ * // `initialize` invokes `createApplication` once
+ */
+ function once(func) {
+ return before(2, func);
+ }
+
+ /**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+ function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
};
- }
+ }
- function eachOf(object, iterator, callback) {
- callback = once(callback || noop);
- object = object || [];
+ /**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+ var getLength = baseProperty('length');
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' &&
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+ }
- var iter = keyIterator(object);
- var key,
- completed = 0;
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null && isLength(getLength(value)) && !isFunction(value);
+ }
- while ((key = iter()) != null) {
- completed += 1;
- iterator(object[key], key, onlyOnce(done));
+ var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator;
+
+ function getIterator (coll) {
+ return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol]();
+ }
+
+ /** Used for built-in method references. */
+ var objectProto$1 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto$1.hasOwnProperty;
+
+ /** Built-in value references. */
+ var getPrototypeOf = Object.getPrototypeOf;
+
+ /**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHas(object, key) {
+ // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+ // that are composed entirely of index properties, return `false` for
+ // `hasOwnProperty` checks of them.
+ return hasOwnProperty.call(object, key) ||
+ (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeKeys = Object.keys;
+
+ /**
+ * The base implementation of `_.keys` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ return nativeKeys(Object(object));
+ }
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
}
+ return result;
+ }
+
+ /**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+ }
- if (completed === 0) callback(null);
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
- function done(err) {
- completed--;
- if (err) {
- callback(err);
- }
- // Check key is null in case iterator isn't exhausted
- // and done resolved synchronously.
- else if (key === null && completed <= 0) {
- callback(null);
- }
+ /** `Object#toString` result references. */
+ var argsTag = '[object Arguments]';
+
+ /** Used for built-in method references. */
+ var objectProto$2 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$1 = objectProto$2.toString;
+
+ /** Built-in value references. */
+ var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
+
+ /**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+ function isArguments(value) {
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty$1.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString$1.call(value) == argsTag);
+ }
+
+ /**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @type {Function}
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+ var isArray = Array.isArray;
+
+ /** `Object#toString` result references. */
+ var stringTag = '[object String]';
+
+ /** Used for built-in method references. */
+ var objectProto$3 = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$2 = objectProto$3.toString;
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+ function isString(value) {
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && objectToString$2.call(value) == stringTag);
+ }
+
+ /**
+ * Creates an array of index keys for `object` values of arrays,
+ * `arguments` objects, and strings, otherwise `null` is returned.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array|null} Returns index keys, else `null`.
+ */
+ function indexKeys(object) {
+ var length = object ? object.length : undefined;
+ if (isLength(length) &&
+ (isArray(object) || isString(object) || isArguments(object))) {
+ return baseTimes(length, String);
}
- }
+ return null;
+ }
- var applyEach = applyEach$1(eachOf);
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER$1 = 9007199254740991;
+
+ /** Used to detect unsigned integer values. */
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+ /**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+ function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER$1 : length;
+ return value > -1 && value % 1 == 0 && value < length;
+ }
- var _setImmediate = typeof setImmediate === 'function' && setImmediate;
+ /** Used for built-in method references. */
+ var objectProto$4 = Object.prototype;
+
+ /**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
+
+ return value === proto;
+ }
- var _delay;
- if (_setImmediate) {
- _delay = function (fn) {
- // not a direct alias for IE10 compatibility
- _setImmediate(fn);
- };
- } else if (typeof process === 'object' && typeof process.nextTick === 'function') {
- _delay = process.nextTick;
- } else {
- _delay = function (fn) {
- setTimeout(fn, 0);
- };
- }
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+ function keys(object) {
+ var isProto = isPrototype(object);
+ if (!(isProto || isArrayLike(object))) {
+ return baseKeys(object);
+ }
+ var indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ for (var key in object) {
+ if (baseHas(object, key) &&
+ !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(isProto && key == 'constructor')) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
- var setImmediate$1 = _delay;
+ function iterator(coll) {
+ var i = -1;
+ var len;
+ if (isArrayLike(coll)) {
+ len = coll.length;
+ return function next() {
+ i++;
+ return i < len ? { value: coll[i], key: i } : null;
+ };
+ }
- function eachOfSeries(obj, iterator, callback) {
- callback = once(callback || noop);
- obj = obj || [];
- var nextKey = keyIterator(obj);
- var key = nextKey();
+ var iterate = getIterator(coll);
+ if (iterate) {
+ return function next() {
+ var item = iterate.next();
+ if (item.done) return null;
+ i++;
+ return { value: item.value, key: i };
+ };
+ }
- function iterate() {
- var sync = true;
- if (key === null) {
- return callback(null);
- }
- iterator(obj[key], key, onlyOnce(function (err) {
- if (err) {
- callback(err);
- } else {
- key = nextKey();
- if (key === null) {
- return callback(null);
- } else {
- if (sync) {
- setImmediate$1(iterate);
- } else {
- iterate();
- }
- }
- }
- }));
- sync = false;
+ var okeys = keys(coll);
+ len = okeys.length;
+ return function next() {
+ i++;
+ var key = okeys[i];
+ return i < len ? { value: coll[key], key: key } : null;
+ };
+ }
+
+ function onlyOnce(fn) {
+ return function () {
+ if (fn === null) throw new Error("Callback was already called.");
+ fn.apply(this, arguments);
+ fn = null;
+ };
+ }
+
+ function _eachOfLimit(limit) {
+ return function (obj, iteratee, callback) {
+ callback = once(callback || noop);
+ obj = obj || [];
+ var nextElem = iterator(obj);
+ if (limit <= 0) {
+ return callback(null);
+ }
+ var done = false;
+ var running = 0;
+ var errored = false;
+
+ (function replenish() {
+ if (done && running <= 0) {
+ return callback(null);
+ }
+
+ while (running < limit && !errored) {
+ var elem = nextElem();
+ if (elem === null) {
+ done = true;
+ if (running <= 0) {
+ callback(null);
+ }
+ return;
+ }
+ running += 1;
+ iteratee(elem.value, elem.key, onlyOnce(function (err) {
+ running -= 1;
+ if (err) {
+ callback(err);
+ errored = true;
+ } else {
+ replenish();
+ }
+ }));
+ }
+ })();
+ };
+ }
+
+ function eachOfLimit(obj, limit, iteratee, cb) {
+ _eachOfLimit(limit)(obj, iteratee, cb);
+ }
+
+ function doLimit(fn, limit) {
+ return function (iterable, iteratee, callback) {
+ return fn(iterable, limit, iteratee, callback);
+ };
+ }
+
+ var eachOf = doLimit(eachOfLimit, Infinity);
+
+ var applyEach = applyEach$1(eachOf);
+
+ var eachOfSeries = doLimit(eachOfLimit, 1);
+
+ var applyEachSeries = applyEach$1(eachOfSeries);
+
+ var apply$1 = rest(function (fn, args) {
+ return rest(function (callArgs) {
+ return fn.apply(null, args.concat(callArgs));
+ });
+ });
+
+ function asyncify(func) {
+ return initialParams(function (args, callback) {
+ var result;
+ try {
+ result = func.apply(this, args);
+ } catch (e) {
+ return callback(e);
+ }
+ // if result is Promise object
+ if (isObject(result) && typeof result.then === 'function') {
+ result.then(function (value) {
+ callback(null, value);
+ })['catch'](function (err) {
+ callback(err.message ? err : new Error(err));
+ });
+ } else {
+ callback(null, result);
+ }
+ });
+ }
+
+ /**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
}
- iterate();
- }
+ return array;
+ }
- var applyEachSeries = applyEach$1(eachOfSeries);
+ /**
+ * This method returns the first argument given to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+ function identity(value) {
+ return value;
+ }
- var apply = rest(function (fn, args) {
- return rest(function (callArgs) {
- return fn.apply(null, args.concat(callArgs));
- });
- });
-
- function asyncify(func) {
- return rest(function (args) {
- var callback = args.pop();
- var result;
- try {
- result = func.apply(this, args);
- } catch (e) {
- return callback(e);
- }
- // if result is Promise object
- if (isObject(result) && typeof result.then === 'function') {
- result.then(function (value) {
- callback(null, value);
- })['catch'](function (err) {
- callback(err.message ? err : new Error(err));
- });
- } else {
- callback(null, result);
+ /**
+ * Casts `value` to `identity` if it's not a function.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the array-like object.
+ */
+ function baseCastFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ /**
+ * Creates a base function for methods like `_.forIn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
}
- });
- }
-
- /**
- * A specialized version of `_.forEach` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns `array`.
- */
- function arrayEach(array, iteratee) {
- var index = -1,
- length = array.length;
-
- while (++index < length) {
- if (iteratee(array[index], index, array) === false) {
- break;
+ }
+ return object;
+ };
+ }
+
+ /**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseFor = createBaseFor();
+
+ /**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys);
+ }
+
+ /**
+ * Iterates over own enumerable properties of an object invoking `iteratee`
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, baseCastFunction(iteratee));
+ }
+
+ /**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+ function indexOfNaN(array, fromIndex, fromRight) {
+ var length = array.length,
+ index = fromIndex + (fromRight ? 0 : -1);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ var other = array[index];
+ if (other !== other) {
+ return index;
+ }
}
+ return -1;
}
- return array;
- }
-
- /**
- * A specialized version of `_.every` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
- */
- function arrayEvery(array, predicate) {
- var index = -1,
- length = array.length;
-
- while (++index < length) {
- if (!predicate(array[index], index, array)) {
- return false;
+
+ /**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseIndexOf(array, value, fromIndex) {
+ if (value !== value) {
+ return indexOfNaN(array, fromIndex);
+ }
+ var index = fromIndex - 1,
+ length = array.length;
+
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
}
+ return -1;
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax$1 = Math.max;
+
+ /**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // Search from the `fromIndex`.
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */
+ function indexOf(array, value, fromIndex) {
+ var length = array ? array.length : 0;
+ if (!length) {
+ return -1;
+ }
+ fromIndex = toInteger(fromIndex);
+ if (fromIndex < 0) {
+ fromIndex = nativeMax$1(length + fromIndex, 0);
+ }
+ return baseIndexOf(array, value, fromIndex);
+ }
+
+ function auto (tasks, concurrency, callback) {
+ if (typeof concurrency === 'function') {
+ // concurrency is optional, shift the args.
+ callback = concurrency;
+ concurrency = null;
+ }
+ callback = once(callback || noop);
+ var keys$$ = keys(tasks);
+ var numTasks = keys$$.length;
+ if (!numTasks) {
+ return callback(null);
+ }
+ if (!concurrency) {
+ concurrency = numTasks;
+ }
+
+ var results = {};
+ var runningTasks = 0;
+ var hasError = false;
+
+ var listeners = {};
+
+ var readyTasks = [];
+
+ forOwn(tasks, function (task, key) {
+ if (!isArray(task)) {
+ // no dependencies
+ enqueueTask(key, [task]);
+ return;
+ }
+
+ var dependencies = task.slice(0, task.length - 1);
+ var remainingDependencies = dependencies.length;
+
+ checkForDeadlocks();
+
+ function checkForDeadlocks() {
+ var len = dependencies.length;
+ var dep;
+ while (len--) {
+ if (!(dep = tasks[dependencies[len]])) {
+ throw new Error('async.auto task `' + key + '` has non-existent dependency in ' + dependencies.join(', '));
+ }
+ if (isArray(dep) && indexOf(dep, key) >= 0) {
+ throw new Error('async.auto task `' + key + '`Has cyclic dependencies');
+ }
+ }
+ }
+
+ arrayEach(dependencies, function (dependencyName) {
+ addListener(dependencyName, function () {
+ remainingDependencies--;
+ if (remainingDependencies === 0) {
+ enqueueTask(key, task);
+ }
+ });
+ });
+ });
+
+ processQueue();
+
+ function enqueueTask(key, task) {
+ readyTasks.push(function () {
+ runTask(key, task);
+ });
+ }
+
+ function processQueue() {
+ if (readyTasks.length === 0 && runningTasks === 0) {
+ return callback(null, results);
+ }
+ while (readyTasks.length && runningTasks < concurrency) {
+ var run = readyTasks.shift();
+ run();
+ }
+ }
+
+ function addListener(taskName, fn) {
+ var taskListeners = listeners[taskName];
+ if (!taskListeners) {
+ taskListeners = listeners[taskName] = [];
+ }
+
+ taskListeners.push(fn);
+ }
+
+ function taskComplete(taskName) {
+ var taskListeners = listeners[taskName] || [];
+ arrayEach(taskListeners, function (fn) {
+ fn();
+ });
+ processQueue();
+ }
+
+ function runTask(key, task) {
+ if (hasError) return;
+
+ var taskCallback = onlyOnce(rest(function (err, args) {
+ runningTasks--;
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ if (err) {
+ var safeResults = {};
+ forOwn(results, function (val, rkey) {
+ safeResults[rkey] = val;
+ });
+ safeResults[key] = args;
+ hasError = true;
+ listeners = [];
+
+ callback(err, safeResults);
+ } else {
+ results[key] = args;
+ taskComplete(key);
+ }
+ }));
+
+ runningTasks++;
+ var taskFn = task[task.length - 1];
+ if (task.length > 1) {
+ taskFn(results, taskCallback);
+ } else {
+ taskFn(taskCallback);
+ }
+ }
}
- return true;
- }
-
- /**
- * Creates a base function for methods like `_.forIn`.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
- function createBaseFor(fromRight) {
- return function(object, iteratee, keysFunc) {
+
+ /**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function arrayMap(array, iteratee) {
var index = -1,
- iterable = Object(object),
- props = keysFunc(object),
- length = props.length;
+ length = array.length,
+ result = Array(length);
+ while (++index < length) {
+ result[index] = iteratee(array[index], index, array);
+ }
+ return result;
+ }
+
+ /**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+ function stackClear() {
+ this.__data__ = { 'array': [], 'map': null };
+ }
+
+ /**
+ * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+ function eq(value, other) {
+ return value === other || (value !== value && other !== other);
+ }
+
+ /**
+ * Gets the index at which the first occurrence of `key` is found in `array`
+ * of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function assocIndexOf(array, key) {
+ var length = array.length;
while (length--) {
- var key = props[fromRight ? length : ++index];
- if (iteratee(iterable[key], key, iterable) === false) {
- break;
+ if (eq(array[length][0], key)) {
+ return length;
}
}
- return object;
- };
- }
-
- /**
- * The base implementation of `baseForIn` and `baseForOwn` which iterates
- * over `object` properties returned by `keysFunc` invoking `iteratee` for
- * each property. Iteratee functions may exit iteration early by explicitly
- * returning `false`.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @returns {Object} Returns `object`.
- */
- var baseFor = createBaseFor();
-
- /**
- * The base implementation of `_.forOwn` without support for iteratee shorthands.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Object} Returns `object`.
- */
- function baseForOwn(object, iteratee) {
- return object && baseFor(object, iteratee, keys);
- }
-
- /**
- * This method returns the first argument given to it.
- *
- * @static
- * @memberOf _
- * @category Util
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'user': 'fred' };
- *
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
-
- /**
- * Converts `value` to a function if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Function} Returns the function.
- */
- function toFunction(value) {
- return typeof value == 'function' ? value : identity;
- }
-
- /**
- * Iterates over own enumerable properties of an object invoking `iteratee`
- * for each property. The iteratee is invoked with three arguments:
- * (value, key, object). Iteratee functions may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.forOwn(new Foo, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'a' then 'b' (iteration order is not guaranteed)
- */
- function forOwn(object, iteratee) {
- return object && baseForOwn(object, toFunction(iteratee));
- }
-
- /**
- * Gets the index at which the first occurrence of `NaN` is found in `array`.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {number} fromIndex The index to search from.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched `NaN`, else `-1`.
- */
- function indexOfNaN(array, fromIndex, fromRight) {
- var length = array.length,
- index = fromIndex + (fromRight ? 0 : -1);
-
- while ((fromRight ? index-- : ++index < length)) {
- var other = array[index];
- if (other !== other) {
- return index;
+ return -1;
+ }
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype;
+
+ /** Built-in value references. */
+ var splice = arrayProto.splice;
+
+ /**
+ * Removes `key` and its value from the associative array.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function assocDelete(array, key) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ return false;
+ }
+ var lastIndex = array.length - 1;
+ if (index == lastIndex) {
+ array.pop();
+ } else {
+ splice.call(array, index, 1);
+ }
+ return true;
+ }
+
+ /**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function stackDelete(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocDelete(array, key) : data.map['delete'](key);
+ }
+
+ /**
+ * Gets the associative array value for `key`.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function assocGet(array, key) {
+ var index = assocIndexOf(array, key);
+ return index < 0 ? undefined : array[index][1];
+ }
+
+ /**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function stackGet(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocGet(array, key) : data.map.get(key);
+ }
+
+ /**
+ * Checks if an associative array value for `key` exists.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function assocHas(array, key) {
+ return assocIndexOf(array, key) > -1;
+ }
+
+ /**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function stackHas(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocHas(array, key) : data.map.has(key);
+ }
+
+ /**
+ * Checks if `value` is a host object in IE < 9.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+ */
+ function isHostObject(value) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ var result = false;
+ if (value != null && typeof value.toString != 'function') {
+ try {
+ result = !!(value + '');
+ } catch (e) {}
}
+ return result;
}
- return -1;
- }
-
- /**
- * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- if (value !== value) {
- return indexOfNaN(array, fromIndex);
- }
- var index = fromIndex - 1,
- length = array.length;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
+
+ /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
+
+ /** Used to detect host constructors (Safari > 5). */
+ var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+ /** Used for built-in method references. */
+ var objectProto$6 = Object.prototype;
+
+ /** Used to resolve the decompiled source of functions. */
+ var funcToString = Function.prototype.toString;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$2 = objectProto$6.hasOwnProperty;
+
+ /** Used to detect if a method is native. */
+ var reIsNative = RegExp('^' +
+ funcToString.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&')
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+ );
+
+ /**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+ function isNative(value) {
+ if (value == null) {
+ return false;
+ }
+ if (isFunction(value)) {
+ return reIsNative.test(funcToString.call(value));
}
+ return isObjectLike(value) &&
+ (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}
- return -1;
- }
-
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeMax$1 = Math.max;
-
- /**
- * Gets the index at which the first occurrence of `value` is found in `array`
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. If `fromIndex` is negative, it's used as the offset
- * from the end of `array`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- * @example
- *
- * _.indexOf([1, 2, 1, 2], 2);
- * // => 1
- *
- * // Search from the `fromIndex`.
- * _.indexOf([1, 2, 1, 2], 2, 2);
- * // => 3
- */
- function indexOf(array, value, fromIndex) {
- var length = array ? array.length : 0;
- if (!length) {
- return -1;
+
+ /**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+ function getNative(object, key) {
+ var value = object[key];
+ return isNative(value) ? value : undefined;
}
- fromIndex = toInteger(fromIndex);
- if (fromIndex < 0) {
- fromIndex = nativeMax$1(length + fromIndex, 0);
+
+ /* Built-in method references that are verified to be native. */
+ var nativeCreate = getNative(Object, 'create');
+
+ /** Used for built-in method references. */
+ var objectProto$5 = Object.prototype;
+
+ /**
+ * Creates an hash object.
+ *
+ * @private
+ * @constructor
+ * @returns {Object} Returns the new hash object.
+ */
+ function Hash() {}
+
+ // Avoid inheriting from `Object.prototype` when possible.
+ Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto$5;
+
+ /**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+ function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
}
- return baseIndexOf(array, value, fromIndex);
- }
- function auto (tasks, concurrency, callback) {
- if (typeof arguments[1] === 'function') {
- // concurrency is optional, shift the args.
- callback = concurrency;
- concurrency = null;
+ /** Used to determine if values are of the language type `Object`. */
+ var objectTypes = {
+ 'function': true,
+ 'object': true
+ };
+
+ /** Detect free variable `exports`. */
+ var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+ ? exports
+ : undefined;
+
+ /** Detect free variable `module`. */
+ var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+ ? module
+ : undefined;
+
+ /** Detect free variable `global` from Node.js. */
+ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+ /** Detect free variable `self`. */
+ var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+ /** Detect free variable `window`. */
+ var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+ /** Detect `this` as the global object. */
+ var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+ /**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+ var root = freeGlobal ||
+ ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+ freeSelf || thisGlobal || Function('return this')();
+
+ /* Built-in method references that are verified to be native. */
+ var Map = getNative(root, 'Map');
+
+ /**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */
+ function mapClear() {
+ this.__data__ = {
+ 'hash': new Hash,
+ 'map': Map ? new Map : [],
+ 'string': new Hash
+ };
+ }
+
+ /** Used for built-in method references. */
+ var objectProto$7 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$3 = objectProto$7.hasOwnProperty;
+
+ /**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function hashHas(hash, key) {
+ return nativeCreate ? hash[key] !== undefined : hasOwnProperty$3.call(hash, key);
+ }
+
+ /**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function hashDelete(hash, key) {
+ return hashHas(hash, key) && delete hash[key];
+ }
+
+ /**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+ function isKeyable(value) {
+ var type = typeof value;
+ return type == 'number' || type == 'boolean' ||
+ (type == 'string' && value != '__proto__') || value == null;
+ }
+
+ /**
+ * Removes `key` and its value from the map.
+ *
+ * @private
+ * @name delete
+ * @memberOf MapCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function mapDelete(key) {
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
}
- callback = once(callback || noop);
- var keys$$ = keys(tasks);
- var remainingTasks = keys$$.length;
- if (!remainingTasks) {
- return callback(null);
+ return Map ? data.map['delete'](key) : assocDelete(data.map, key);
+ }
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /** Used for built-in method references. */
+ var objectProto$8 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$4 = objectProto$8.hasOwnProperty;
+
+ /**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function hashGet(hash, key) {
+ if (nativeCreate) {
+ var result = hash[key];
+ return result === HASH_UNDEFINED ? undefined : result;
}
- if (!concurrency) {
- concurrency = remainingTasks;
+ return hasOwnProperty$4.call(hash, key) ? hash[key] : undefined;
+ }
+
+ /**
+ * Gets the map value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf MapCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function mapGet(key) {
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashGet(typeof key == 'string' ? data.string : data.hash, key);
}
+ return Map ? data.map.get(key) : assocGet(data.map, key);
+ }
- var results = {};
- var runningTasks = 0;
- var hasError = false;
+ /**
+ * Checks if a map value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf MapCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function mapHas(key) {
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashHas(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map.has(key) : assocHas(data.map, key);
+ }
- var listeners = [];
- function addListener(fn) {
- listeners.unshift(fn);
+ /**
+ * Sets the associative array `key` to `value`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ */
+ function assocSet(array, key, value) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ array.push([key, value]);
+ } else {
+ array[index][1] = value;
}
- function removeListener(fn) {
- var idx = indexOf(listeners, fn);
- if (idx >= 0) listeners.splice(idx, 1);
+ }
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
+
+ /**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ */
+ function hashSet(hash, key, value) {
+ hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
+ }
+
+ /**
+ * Sets the map `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache object.
+ */
+ function mapSet(key, value) {
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
+ } else if (Map) {
+ data.map.set(key, value);
+ } else {
+ assocSet(data.map, key, value);
}
- function taskComplete() {
- remainingTasks--;
- arrayEach(listeners.slice(), function (fn) {
- fn();
- });
+ return this;
+ }
+
+ /**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [values] The values to cache.
+ */
+ function MapCache(values) {
+ var index = -1,
+ length = values ? values.length : 0;
+
+ this.clear();
+ while (++index < length) {
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
}
+ }
- addListener(function () {
- if (!remainingTasks) {
- callback(null, results);
- }
- });
+ // Add functions to the `MapCache`.
+ MapCache.prototype.clear = mapClear;
+ MapCache.prototype['delete'] = mapDelete;
+ MapCache.prototype.get = mapGet;
+ MapCache.prototype.has = mapHas;
+ MapCache.prototype.set = mapSet;
+
+ /** Used as the size to enable large array optimizations. */
+ var LARGE_ARRAY_SIZE = 200;
+
+ /**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache object.
+ */
+ function stackSet(key, value) {
+ var data = this.__data__,
+ array = data.array;
+
+ if (array) {
+ if (array.length < (LARGE_ARRAY_SIZE - 1)) {
+ assocSet(array, key, value);
+ } else {
+ data.array = null;
+ data.map = new MapCache(array);
+ }
+ }
+ var map = data.map;
+ if (map) {
+ map.set(key, value);
+ }
+ return this;
+ }
- arrayEach(keys$$, function (k) {
- if (hasError) return;
- var task = isArray(tasks[k]) ? tasks[k] : [tasks[k]];
- var taskCallback = rest(function (err, args) {
- runningTasks--;
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- forOwn(results, function (val, rkey) {
- safeResults[rkey] = val;
- });
- safeResults[k] = args;
- hasError = true;
-
- callback(err, safeResults);
- } else {
- results[k] = args;
- setImmediate$1(taskComplete);
- }
- });
- var requires = task.slice(0, task.length - 1);
- // prevent dead-locks
- var len = requires.length;
- var dep;
- while (len--) {
- if (!(dep = tasks[requires[len]])) {
- throw new Error('Has non-existent dependency in ' + requires.join(', '));
- }
- if (isArray(dep) && indexOf(dep, k) >= 0) {
- throw new Error('Has cyclic dependencies');
- }
- }
- function ready() {
- return runningTasks < concurrency && !baseHas(results, k) && arrayEvery(requires, function (x) {
- return baseHas(results, x);
- });
- }
- if (ready()) {
- runningTasks++;
- task[task.length - 1](taskCallback, results);
- } else {
- addListener(listener);
- }
- function listener() {
- if (ready()) {
- runningTasks++;
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- }
- });
- }
-
- /**
- * A specialized version of `_.map` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
- function arrayMap(array, iteratee) {
- var index = -1,
- length = array.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iteratee(array[index], index, array);
- }
- return result;
- }
-
- function queue$1(worker, concurrency, payload) {
- if (concurrency == null) {
- concurrency = 1;
- } else if (concurrency === 0) {
- throw new Error('Concurrency must not be zero');
+ /**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [values] The values to cache.
+ */
+ function Stack(values) {
+ var index = -1,
+ length = values ? values.length : 0;
+
+ this.clear();
+ while (++index < length) {
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
}
- function _insert(q, data, pos, callback) {
- if (callback != null && typeof callback !== 'function') {
- throw new Error('task callback must be a function');
- }
- q.started = true;
- if (!isArray(data)) {
- data = [data];
- }
- if (data.length === 0 && q.idle()) {
- // call drain immediately if there are no tasks
- return setImmediate$1(function () {
- q.drain();
- });
- }
- arrayEach(data, function (task) {
- var item = {
- data: task,
- callback: callback || noop
- };
-
- if (pos) {
- q.tasks.unshift(item);
- } else {
- q.tasks.push(item);
- }
-
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- });
- setImmediate$1(q.process);
+ }
+
+ // Add functions to the `Stack` cache.
+ Stack.prototype.clear = stackClear;
+ Stack.prototype['delete'] = stackDelete;
+ Stack.prototype.get = stackGet;
+ Stack.prototype.has = stackHas;
+ Stack.prototype.set = stackSet;
+
+ /** Used for built-in method references. */
+ var objectProto$9 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$5 = objectProto$9.hasOwnProperty;
+
+ /**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignValue(object, key, value) {
+ var objValue = object[key];
+ if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) ||
+ (value === undefined && !(key in object))) {
+ object[key] = value;
}
- function _next(q, tasks) {
- return function () {
- workers -= 1;
-
- var removed = false;
- var args = arguments;
- arrayEach(tasks, function (task) {
- arrayEach(workersList, function (worker, index) {
- if (worker === task && !removed) {
- workersList.splice(index, 1);
- removed = true;
- }
- });
-
- task.callback.apply(task, args);
- });
- if (q.tasks.length + workers === 0) {
- q.drain();
- }
- q.process();
- };
+ }
+
+ /**
+ * This function is like `copyObject` except that it accepts a function to
+ * customize copied values.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObjectWith(source, props, object, customizer) {
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index];
+
+ var newValue = customizer
+ ? customizer(object[key], source[key], key, object, source)
+ : source[key];
+
+ assignValue(object, key, newValue);
}
+ return object;
+ }
+
+ /**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObject(source, props, object) {
+ return copyObjectWith(source, props, object);
+ }
+
+ /**
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+ function baseAssign(object, source) {
+ return object && copyObject(source, keys(source), object);
+ }
- var workers = 0;
- var workersList = [];
- var q = {
- tasks: [],
- concurrency: concurrency,
- payload: payload,
- saturated: noop,
- empty: noop,
- drain: noop,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(q, data, false, callback);
- },
- kill: function () {
- q.drain = noop;
- q.tasks = [];
- },
- unshift: function (data, callback) {
- _insert(q, data, true, callback);
- },
- process: function () {
- while (!q.paused && workers < q.concurrency && q.tasks.length) {
-
- var tasks = q.payload ? q.tasks.splice(0, q.payload) : q.tasks.splice(0, q.tasks.length);
-
- var data = arrayMap(tasks, baseProperty('data'));
-
- if (q.tasks.length === 0) {
- q.empty();
- }
- workers += 1;
- workersList.push(tasks[0]);
- var cb = onlyOnce(_next(q, tasks));
- worker(data, cb);
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- },
- workersList: function () {
- return workersList;
- },
- idle: function () {
- return q.tasks.length + workers === 0;
- },
- pause: function () {
- q.paused = true;
- },
- resume: function () {
- if (q.paused === false) {
- return;
- }
- q.paused = false;
- var resumeCount = Math.min(q.concurrency, q.tasks.length);
- // Need to call q.process once per concurrent
- // worker to preserve full concurrency after pause
- for (var w = 1; w <= resumeCount; w++) {
- setImmediate$1(q.process);
- }
+ /**
+ * Creates a clone of `buffer`.
+ *
+ * @private
+ * @param {Buffer} buffer The buffer to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Buffer} Returns the cloned buffer.
+ */
+ function cloneBuffer(buffer, isDeep) {
+ if (isDeep) {
+ return buffer.slice();
+ }
+ var result = new buffer.constructor(buffer.length);
+ buffer.copy(result);
+ return result;
+ }
+
+ /**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+ function copyArray(source, array) {
+ var index = -1,
+ length = source.length;
+
+ array || (array = Array(length));
+ while (++index < length) {
+ array[index] = source[index];
+ }
+ return array;
+ }
+
+ /** Built-in value references. */
+ var getOwnPropertySymbols = Object.getOwnPropertySymbols;
+
+ /**
+ * Creates an array of the own symbol properties of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+ var getSymbols = getOwnPropertySymbols || function() {
+ return [];
+ };
+
+ /**
+ * Copies own symbol properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+ function copySymbols(source, object) {
+ return copyObject(source, getSymbols(source), object);
+ }
+
+ /* Built-in method references that are verified to be native. */
+ var Set = getNative(root, 'Set');
+
+ /* Built-in method references that are verified to be native. */
+ var WeakMap = getNative(root, 'WeakMap');
+
+ var mapTag$1 = '[object Map]';
+ var objectTag$1 = '[object Object]';
+ var setTag$1 = '[object Set]';
+ var weakMapTag$1 = '[object WeakMap]';
+ /** Used for built-in method references. */
+ var objectProto$10 = Object.prototype;
+
+ /** Used to resolve the decompiled source of functions. */
+ var funcToString$1 = Function.prototype.toString;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$3 = objectProto$10.toString;
+
+ /** Used to detect maps, sets, and weakmaps. */
+ var mapCtorString = Map ? funcToString$1.call(Map) : '';
+ var setCtorString = Set ? funcToString$1.call(Set) : '';
+ var weakMapCtorString = WeakMap ? funcToString$1.call(WeakMap) : '';
+ /**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+ function getTag(value) {
+ return objectToString$3.call(value);
+ }
+
+ // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
+ if ((Map && getTag(new Map) != mapTag$1) ||
+ (Set && getTag(new Set) != setTag$1) ||
+ (WeakMap && getTag(new WeakMap) != weakMapTag$1)) {
+ getTag = function(value) {
+ var result = objectToString$3.call(value),
+ Ctor = result == objectTag$1 ? value.constructor : null,
+ ctorString = typeof Ctor == 'function' ? funcToString$1.call(Ctor) : '';
+
+ if (ctorString) {
+ switch (ctorString) {
+ case mapCtorString: return mapTag$1;
+ case setCtorString: return setTag$1;
+ case weakMapCtorString: return weakMapTag$1;
}
+ }
+ return result;
};
- return q;
- }
-
- function cargo(worker, payload) {
- return queue$1(worker, 1, payload);
- }
-
- function reduce(arr, memo, iterator, cb) {
- eachOfSeries(arr, function (x, i, cb) {
- iterator(memo, x, function (err, v) {
- memo = v;
- cb(err);
- });
- }, function (err) {
- cb(err, memo);
- });
- }
-
- function seq() /* functions... */{
- var fns = arguments;
- return rest(function (args) {
- var that = this;
-
- var cb = args[args.length - 1];
- if (typeof cb == 'function') {
- args.pop();
- } else {
- cb = noop;
- }
+ }
+
+ var getTag$1 = getTag;
+
+ /** Used for built-in method references. */
+ var objectProto$11 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$6 = objectProto$11.hasOwnProperty;
+
+ /**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+ function initCloneArray(array) {
+ var length = array.length,
+ result = array.constructor(length);
+
+ // Add properties assigned by `RegExp#exec`.
+ if (length && typeof array[0] == 'string' && hasOwnProperty$6.call(array, 'index')) {
+ result.index = array.index;
+ result.input = array.input;
+ }
+ return result;
+ }
+
+ /** Built-in value references. */
+ var Uint8Array = root.Uint8Array;
+
+ /**
+ * Creates a clone of `arrayBuffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+ function cloneArrayBuffer(arrayBuffer) {
+ var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
+ new Uint8Array(result).set(new Uint8Array(arrayBuffer));
+ return result;
+ }
+
+ /**
+ * Adds the key-value `pair` to `map`.
+ *
+ * @private
+ * @param {Object} map The map to modify.
+ * @param {Array} pair The key-value pair to add.
+ * @returns {Object} Returns `map`.
+ */
+ function addMapEntry(map, pair) {
+ // Don't return `Map#set` because it doesn't return the map instance in IE 11.
+ map.set(pair[0], pair[1]);
+ return map;
+ }
+
+ /**
+ * A specialized version of `_.reduce` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+ function arrayReduce(array, iteratee, accumulator, initAccum) {
+ var index = -1,
+ length = array.length;
+
+ if (initAccum && length) {
+ accumulator = array[++index];
+ }
+ while (++index < length) {
+ accumulator = iteratee(accumulator, array[index], index, array);
+ }
+ return accumulator;
+ }
- reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([rest(function (err, nextargs) {
- cb(err, nextargs);
- })]));
- }, function (err, results) {
- cb.apply(that, [err].concat(results));
- });
+ /**
+ * Converts `map` to an array.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function mapToArray(map) {
+ var index = -1,
+ result = Array(map.size);
+
+ map.forEach(function(value, key) {
+ result[++index] = [key, value];
});
- }
+ return result;
+ }
- var reverse = Array.prototype.reverse;
+ /**
+ * Creates a clone of `map`.
+ *
+ * @private
+ * @param {Object} map The map to clone.
+ * @returns {Object} Returns the cloned map.
+ */
+ function cloneMap(map) {
+ return arrayReduce(mapToArray(map), addMapEntry, new map.constructor);
+ }
- function compose() /* functions... */{
- return seq.apply(null, reverse.call(arguments));
- }
+ /** Used to match `RegExp` flags from their coerced string values. */
+ var reFlags = /\w*$/;
+
+ /**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */
+ function cloneRegExp(regexp) {
+ var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
+ result.lastIndex = regexp.lastIndex;
+ return result;
+ }
- function concat$1(eachfn, arr, fn, callback) {
- var result = [];
- eachfn(arr, function (x, index, cb) {
- fn(x, function (err, y) {
- result = result.concat(y || []);
- cb(err);
- });
- }, function (err) {
- callback(err, result);
+ /**
+ * Adds `value` to `set`.
+ *
+ * @private
+ * @param {Object} set The set to modify.
+ * @param {*} value The value to add.
+ * @returns {Object} Returns `set`.
+ */
+ function addSetEntry(set, value) {
+ set.add(value);
+ return set;
+ }
+
+ /**
+ * Converts `set` to an array.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function setToArray(set) {
+ var index = -1,
+ result = Array(set.size);
+
+ set.forEach(function(value) {
+ result[++index] = value;
});
- }
+ return result;
+ }
- function doParallel(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOf, obj, iterator, callback);
- };
- }
+ /**
+ * Creates a clone of `set`.
+ *
+ * @private
+ * @param {Object} set The set to clone.
+ * @returns {Object} Returns the cloned set.
+ */
+ function cloneSet(set) {
+ return arrayReduce(setToArray(set), addSetEntry, new set.constructor);
+ }
+
+ /** Built-in value references. */
+ var Symbol$1 = root.Symbol;
+
+ var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined;
+ var symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
+ /**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */
+ function cloneSymbol(symbol) {
+ return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
+ }
- var concat = doParallel(concat$1);
+ /**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+ function cloneTypedArray(typedArray, isDeep) {
+ var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
+ return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+ }
- function doSeries(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOfSeries, obj, iterator, callback);
- };
- }
+ var boolTag$1 = '[object Boolean]';
+ var dateTag$1 = '[object Date]';
+ var mapTag$2 = '[object Map]';
+ var numberTag$1 = '[object Number]';
+ var regexpTag$1 = '[object RegExp]';
+ var setTag$2 = '[object Set]';
+ var stringTag$2 = '[object String]';
+ var symbolTag$1 = '[object Symbol]';
+ var arrayBufferTag$1 = '[object ArrayBuffer]';
+ var float32Tag$1 = '[object Float32Array]';
+ var float64Tag$1 = '[object Float64Array]';
+ var int8Tag$1 = '[object Int8Array]';
+ var int16Tag$1 = '[object Int16Array]';
+ var int32Tag$1 = '[object Int32Array]';
+ var uint8Tag$1 = '[object Uint8Array]';
+ var uint8ClampedTag$1 = '[object Uint8ClampedArray]';
+ var uint16Tag$1 = '[object Uint16Array]';
+ var uint32Tag$1 = '[object Uint32Array]';
+ /**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+ function initCloneByTag(object, tag, isDeep) {
+ var Ctor = object.constructor;
+ switch (tag) {
+ case arrayBufferTag$1:
+ return cloneArrayBuffer(object);
+
+ case boolTag$1:
+ case dateTag$1:
+ return new Ctor(+object);
+
+ case float32Tag$1: case float64Tag$1:
+ case int8Tag$1: case int16Tag$1: case int32Tag$1:
+ case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
+ return cloneTypedArray(object, isDeep);
+
+ case mapTag$2:
+ return cloneMap(object);
+
+ case numberTag$1:
+ case stringTag$2:
+ return new Ctor(object);
+
+ case regexpTag$1:
+ return cloneRegExp(object);
+
+ case setTag$2:
+ return cloneSet(object);
+
+ case symbolTag$1:
+ return cloneSymbol(object);
+ }
+ }
- var concatSeries = doSeries(concat$1);
+ /** Built-in value references. */
+ var objectCreate = Object.create;
+
+ /**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} prototype The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+ function baseCreate(proto) {
+ return isObject(proto) ? objectCreate(proto) : {};
+ }
+
+ /** Built-in value references. */
+ var getPrototypeOf$1 = Object.getPrototypeOf;
+
+ /**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+ function initCloneObject(object) {
+ return (typeof object.constructor == 'function' && !isPrototype(object))
+ ? baseCreate(getPrototypeOf$1(object))
+ : {};
+ }
- var constant = rest(function (values) {
- var args = [null].concat(values);
- return function (cb) {
- return cb.apply(this, args);
+ /**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var getter = _.constant(object);
+ *
+ * getter() === object;
+ * // => true
+ */
+ function constant(value) {
+ return function() {
+ return value;
};
- });
-
- function _createTester(eachfn, check, getResult) {
- return function (arr, limit, iterator, cb) {
- function done(err) {
- if (cb) {
- if (err) {
- cb(err);
- } else {
- cb(null, getResult(false, void 0));
- }
- }
+ }
+
+ /** Used to determine if values are of the language type `Object`. */
+ var objectTypes$1 = {
+ 'function': true,
+ 'object': true
+ };
+
+ /** Detect free variable `exports`. */
+ var freeExports$1 = (objectTypes$1[typeof exports] && exports && !exports.nodeType)
+ ? exports
+ : undefined;
+
+ /** Detect free variable `module`. */
+ var freeModule$1 = (objectTypes$1[typeof module] && module && !module.nodeType)
+ ? module
+ : undefined;
+
+ /** Detect the popular CommonJS extension `module.exports`. */
+ var moduleExports = (freeModule$1 && freeModule$1.exports === freeExports$1)
+ ? freeExports$1
+ : undefined;
+
+ /** Built-in value references. */
+ var Buffer = moduleExports ? root.Buffer : undefined;
+
+ /**
+ * Checks if `value` is a buffer.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */
+ var isBuffer = !Buffer ? constant(false) : function(value) {
+ return value instanceof Buffer;
+ };
+
+ var argsTag$1 = '[object Arguments]';
+ var arrayTag = '[object Array]';
+ var boolTag = '[object Boolean]';
+ var dateTag = '[object Date]';
+ var errorTag = '[object Error]';
+ var funcTag$1 = '[object Function]';
+ var genTag$1 = '[object GeneratorFunction]';
+ var mapTag = '[object Map]';
+ var numberTag = '[object Number]';
+ var objectTag = '[object Object]';
+ var regexpTag = '[object RegExp]';
+ var setTag = '[object Set]';
+ var stringTag$1 = '[object String]';
+ var symbolTag = '[object Symbol]';
+ var weakMapTag = '[object WeakMap]';
+ var arrayBufferTag = '[object ArrayBuffer]';
+ var float32Tag = '[object Float32Array]';
+ var float64Tag = '[object Float64Array]';
+ var int8Tag = '[object Int8Array]';
+ var int16Tag = '[object Int16Array]';
+ var int32Tag = '[object Int32Array]';
+ var uint8Tag = '[object Uint8Array]';
+ var uint8ClampedTag = '[object Uint8ClampedArray]';
+ var uint16Tag = '[object Uint16Array]';
+ var uint32Tag = '[object Uint32Array]';
+ /** Used to identify `toStringTag` values supported by `_.clone`. */
+ var cloneableTags = {};
+ cloneableTags[argsTag$1] = cloneableTags[arrayTag] =
+ cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+ cloneableTags[dateTag] = cloneableTags[float32Tag] =
+ cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+ cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+ cloneableTags[mapTag] = cloneableTags[numberTag] =
+ cloneableTags[objectTag] = cloneableTags[regexpTag] =
+ cloneableTags[setTag] = cloneableTags[stringTag$1] =
+ cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
+ cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
+ cloneableTags[uint32Tag] = true;
+ cloneableTags[errorTag] = cloneableTags[funcTag$1] =
+ cloneableTags[weakMapTag] = false;
+
+ /**
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @param {boolean} [isFull] Specify a clone including symbols.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+ function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
+ var result;
+ if (customizer) {
+ result = object ? customizer(value, key, object, stack) : customizer(value);
+ }
+ if (result !== undefined) {
+ return result;
+ }
+ if (!isObject(value)) {
+ return value;
+ }
+ var isArr = isArray(value);
+ if (isArr) {
+ result = initCloneArray(value);
+ if (!isDeep) {
+ return copyArray(value, result);
+ }
+ } else {
+ var tag = getTag$1(value),
+ isFunc = tag == funcTag$1 || tag == genTag$1;
+
+ if (isBuffer(value)) {
+ return cloneBuffer(value, isDeep);
+ }
+ if (tag == objectTag || tag == argsTag$1 || (isFunc && !object)) {
+ if (isHostObject(value)) {
+ return object ? value : {};
}
- function iteratee(x, _, callback) {
- if (!cb) return callback();
- iterator(x, function (err, v) {
- if (cb) {
- if (err) {
- cb(err);
- cb = iterator = false;
- } else if (check(v)) {
- cb(null, getResult(true, x));
- cb = iterator = false;
- }
- }
- callback();
- });
+ result = initCloneObject(isFunc ? {} : value);
+ if (!isDeep) {
+ result = baseAssign(result, value);
+ return isFull ? copySymbols(value, result) : result;
}
- if (arguments.length > 3) {
- eachfn(arr, limit, iteratee, done);
- } else {
- cb = iterator;
- iterator = limit;
- eachfn(arr, iteratee, done);
+ } else {
+ if (!cloneableTags[tag]) {
+ return object ? value : {};
}
- };
- }
+ result = initCloneByTag(value, tag, isDeep);
+ }
+ }
+ // Check for circular references and return its corresponding clone.
+ stack || (stack = new Stack);
+ var stacked = stack.get(value);
+ if (stacked) {
+ return stacked;
+ }
+ stack.set(value, result);
- function _findGetResult(v, x) {
- return x;
- }
+ // Recursively populate clone (susceptible to call stack limits).
+ (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+ assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
+ });
+ return (isFull && !isArr) ? copySymbols(value, result) : result;
+ }
- var detect = _createTester(eachOf, identity, _findGetResult);
+ var argsRegex = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
- function _eachOfLimit(limit) {
- return function (obj, iterator, callback) {
- callback = once(callback || noop);
- obj = obj || [];
- var nextKey = keyIterator(obj);
- if (limit <= 0) {
- return callback(null);
- }
- var done = false;
- var running = 0;
- var errored = false;
-
- (function replenish() {
- if (done && running <= 0) {
- return callback(null);
- }
-
- while (running < limit && !errored) {
- var key = nextKey();
- if (key === null) {
- done = true;
- if (running <= 0) {
- callback(null);
- }
- return;
- }
- running += 1;
- iterator(obj[key], key, onlyOnce(function (err) {
- running -= 1;
- if (err) {
- callback(err);
- errored = true;
- } else {
- replenish();
- }
- }));
- }
- })();
- };
- }
-
- function eachOfLimit(obj, limit, iterator, cb) {
- _eachOfLimit(limit)(obj, iterator, cb);
- }
-
- var detectLimit = _createTester(eachOfLimit, identity, _findGetResult);
-
- var detectSeries = _createTester(eachOfSeries, identity, _findGetResult);
-
- function consoleFunc(name) {
- return rest(function (fn, args) {
- fn.apply(null, args.concat([rest(function (err, args) {
- if (typeof console === 'object') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- } else if (console[name]) {
- arrayEach(args, function (x) {
- console[name](x);
- });
- }
- }
- })]));
- });
- }
+ function parseParams(func) {
+ return func.toString().match(argsRegex)[1].split(/\s*\,\s*/);
+ }
- var dir = consoleFunc('dir');
+ function autoInject(tasks, callback) {
+ var newTasks = {};
+
+ forOwn(tasks, function (taskFn, key) {
+ var params;
+
+ if (isArray(taskFn)) {
+ params = baseClone(taskFn);
+ taskFn = params.pop();
+
+ newTasks[key] = params.concat(newTask);
+ } else if (taskFn.length === 0) {
+ throw new Error("autoInject task functions require explicit parameters.");
+ } else if (taskFn.length === 1) {
+ // no dependencies, use the function as-is
+ newTasks[key] = taskFn;
+ } else {
+ params = parseParams(taskFn);
+ params.pop();
+
+ newTasks[key] = params.concat(newTask);
+ }
+
+ function newTask(results, taskCb) {
+ var newArgs = arrayMap(params, function (name) {
+ return results[name];
+ });
+ newArgs.push(taskCb);
+ taskFn.apply(null, newArgs);
+ }
+ });
+
+ auto(newTasks, callback);
+ }
- function during(test, iterator, cb) {
- cb = cb || noop;
+ var _setImmediate = typeof setImmediate === 'function' && setImmediate;
+
+ var _defer;
+ if (_setImmediate) {
+ _defer = _setImmediate;
+ } else if (typeof process === 'object' && typeof process.nextTick === 'function') {
+ _defer = process.nextTick;
+ } else {
+ _defer = function (fn) {
+ setTimeout(fn, 0);
+ };
+ }
- var next = rest(function (err, args) {
- if (err) {
- cb(err);
- } else {
- args.push(check);
- test.apply(this, args);
- }
- });
+ var setImmediate$1 = rest(function (fn, args) {
+ _defer(function () {
+ fn.apply(null, args);
+ });
+ });
- var check = function (err, truth) {
- if (err) return cb(err);
- if (!truth) return cb(null);
- iterator(next);
- };
+ function queue(worker, concurrency, payload) {
+ if (concurrency == null) {
+ concurrency = 1;
+ } else if (concurrency === 0) {
+ throw new Error('Concurrency must not be zero');
+ }
+ function _insert(q, data, pos, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!isArray(data)) {
+ data = [data];
+ }
+ if (data.length === 0 && q.idle()) {
+ // call drain immediately if there are no tasks
+ return setImmediate$1(function () {
+ q.drain();
+ });
+ }
+ arrayEach(data, function (task) {
+ var item = {
+ data: task,
+ callback: callback || noop
+ };
+
+ if (pos) {
+ q.tasks.unshift(item);
+ } else {
+ q.tasks.push(item);
+ }
+ });
+ setImmediate$1(q.process);
+ }
+ function _next(q, tasks) {
+ return function () {
+ workers -= 1;
+
+ var removed = false;
+ var args = arguments;
+ arrayEach(tasks, function (task) {
+ arrayEach(workersList, function (worker, index) {
+ if (worker === task && !removed) {
+ workersList.splice(index, 1);
+ removed = true;
+ }
+ });
+
+ task.callback.apply(task, args);
+ });
+
+ if (workers <= q.concurrency - q.buffer) {
+ q.unsaturated();
+ }
+
+ if (q.tasks.length + workers === 0) {
+ q.drain();
+ }
+ q.process();
+ };
+ }
- test(check);
- }
-
- function doDuring(iterator, test, cb) {
- var calls = 0;
-
- during(function (next) {
- if (calls++ < 1) return next(null, true);
- test.apply(this, arguments);
- }, iterator, cb);
- }
-
- function whilst(test, iterator, cb) {
- cb = cb || noop;
- if (!test()) return cb(null);
- var next = rest(function (err, args) {
- if (err) return cb(err);
- if (test.apply(this, args)) return iterator(next);
- cb.apply(null, [null].concat(args));
- });
- iterator(next);
- }
-
- function doWhilst(iterator, test, cb) {
- var calls = 0;
- return whilst(function () {
- return ++calls <= 1 || test.apply(this, arguments);
- }, iterator, cb);
- }
-
- function doUntil(iterator, test, cb) {
- return doWhilst(iterator, function () {
- return !test.apply(this, arguments);
- }, cb);
- }
-
- function _withoutIndex(iterator) {
- return function (value, index, callback) {
- return iterator(value, callback);
- };
- }
-
- function each(arr, iterator, cb) {
- return eachOf(arr, _withoutIndex(iterator), cb);
- }
-
- function eachLimit(arr, limit, iterator, cb) {
- return _eachOfLimit(limit)(arr, _withoutIndex(iterator), cb);
- }
-
- function eachSeries(arr, iterator, cb) {
- return eachOfSeries(arr, _withoutIndex(iterator), cb);
- }
-
- function ensureAsync(fn) {
- return rest(function (args) {
- var callback = args.pop();
- var sync = true;
- args.push(function () {
- var innerArgs = arguments;
- if (sync) {
- setImmediate$1(function () {
- callback.apply(null, innerArgs);
- });
- } else {
- callback.apply(null, innerArgs);
- }
- });
- fn.apply(this, args);
- sync = false;
- });
- }
-
- function notId(v) {
- return !v;
- }
-
- var every = _createTester(eachOf, notId, notId);
-
- var everyLimit = _createTester(eachOfLimit, notId, notId);
-
- function _filter(eachfn, arr, iterator, callback) {
- var results = [];
- eachfn(arr, function (x, index, callback) {
- iterator(x, function (err, v) {
- if (err) {
- callback(err);
- } else {
- if (v) {
- results.push({ index: index, value: x });
- }
- callback();
- }
- });
- }, function (err) {
- if (err) {
- callback(err);
- } else {
- callback(null, arrayMap(results.sort(function (a, b) {
- return a.index - b.index;
- }), baseProperty('value')));
- }
- });
- }
+ var workers = 0;
+ var workersList = [];
+ var q = {
+ tasks: [],
+ concurrency: concurrency,
+ payload: payload,
+ saturated: noop,
+ unsaturated: noop,
+ buffer: concurrency / 4,
+ empty: noop,
+ drain: noop,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(q, data, false, callback);
+ },
+ kill: function () {
+ q.drain = noop;
+ q.tasks = [];
+ },
+ unshift: function (data, callback) {
+ _insert(q, data, true, callback);
+ },
+ process: function () {
+ while (!q.paused && workers < q.concurrency && q.tasks.length) {
+
+ var tasks = q.payload ? q.tasks.splice(0, q.payload) : q.tasks.splice(0, q.tasks.length);
+
+ var data = arrayMap(tasks, baseProperty('data'));
+
+ if (q.tasks.length === 0) {
+ q.empty();
+ }
+ workers += 1;
+ workersList.push(tasks[0]);
+
+ if (workers === q.concurrency) {
+ q.saturated();
+ }
+
+ var cb = onlyOnce(_next(q, tasks));
+ worker(data, cb);
+ }
+ },
+ length: function () {
+ return q.tasks.length;
+ },
+ running: function () {
+ return workers;
+ },
+ workersList: function () {
+ return workersList;
+ },
+ idle: function () {
+ return q.tasks.length + workers === 0;
+ },
+ pause: function () {
+ q.paused = true;
+ },
+ resume: function () {
+ if (q.paused === false) {
+ return;
+ }
+ q.paused = false;
+ var resumeCount = Math.min(q.concurrency, q.tasks.length);
+ // Need to call q.process once per concurrent
+ // worker to preserve full concurrency after pause
+ for (var w = 1; w <= resumeCount; w++) {
+ setImmediate$1(q.process);
+ }
+ }
+ };
+ return q;
+ }
+
+ function cargo(worker, payload) {
+ return queue(worker, 1, payload);
+ }
- var filter = doParallel(_filter);
+ function reduce(arr, memo, iteratee, cb) {
+ eachOfSeries(arr, function (x, i, cb) {
+ iteratee(memo, x, function (err, v) {
+ memo = v;
+ cb(err);
+ });
+ }, function (err) {
+ cb(err, memo);
+ });
+ }
- function doParallelLimit(fn) {
- return function (obj, limit, iterator, callback) {
- return fn(_eachOfLimit(limit), obj, iterator, callback);
- };
- }
+ function seq() /* functions... */{
+ var fns = arguments;
+ return rest(function (args) {
+ var that = this;
+
+ var cb = args[args.length - 1];
+ if (typeof cb == 'function') {
+ args.pop();
+ } else {
+ cb = noop;
+ }
+
+ reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([rest(function (err, nextargs) {
+ cb(err, nextargs);
+ })]));
+ }, function (err, results) {
+ cb.apply(that, [err].concat(results));
+ });
+ });
+ }
- var filterLimit = doParallelLimit(_filter);
+ var reverse = Array.prototype.reverse;
- var filterSeries = doSeries(_filter);
+ function compose() /* functions... */{
+ return seq.apply(null, reverse.call(arguments));
+ }
+
+ function concat$1(eachfn, arr, fn, callback) {
+ var result = [];
+ eachfn(arr, function (x, index, cb) {
+ fn(x, function (err, y) {
+ result = result.concat(y || []);
+ cb(err);
+ });
+ }, function (err) {
+ callback(err, result);
+ });
+ }
+
+ function doParallel(fn) {
+ return function (obj, iteratee, callback) {
+ return fn(eachOf, obj, iteratee, callback);
+ };
+ }
+
+ var concat = doParallel(concat$1);
+
+ function doSeries(fn) {
+ return function (obj, iteratee, callback) {
+ return fn(eachOfSeries, obj, iteratee, callback);
+ };
+ }
+
+ var concatSeries = doSeries(concat$1);
+
+ var constant$1 = rest(function (values) {
+ var args = [null].concat(values);
+ return initialParams(function (ignoredArgs, callback) {
+ return callback.apply(this, args);
+ });
+ });
+
+ function _createTester(eachfn, check, getResult) {
+ return function (arr, limit, iteratee, cb) {
+ function done(err) {
+ if (cb) {
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, getResult(false));
+ }
+ }
+ }
+ function wrappedIteratee(x, _, callback) {
+ if (!cb) return callback();
+ iteratee(x, function (err, v) {
+ if (cb) {
+ if (err) {
+ cb(err);
+ cb = iteratee = false;
+ } else if (check(v)) {
+ cb(null, getResult(true, x));
+ cb = iteratee = false;
+ }
+ }
+ callback();
+ });
+ }
+ if (arguments.length > 3) {
+ eachfn(arr, limit, wrappedIteratee, done);
+ } else {
+ cb = iteratee;
+ iteratee = limit;
+ eachfn(arr, wrappedIteratee, done);
+ }
+ };
+ }
+
+ function _findGetResult(v, x) {
+ return x;
+ }
+
+ var detect = _createTester(eachOf, identity, _findGetResult);
+
+ var detectLimit = _createTester(eachOfLimit, identity, _findGetResult);
+
+ var detectSeries = _createTester(eachOfSeries, identity, _findGetResult);
+
+ function consoleFunc(name) {
+ return rest(function (fn, args) {
+ fn.apply(null, args.concat([rest(function (err, args) {
+ if (typeof console === 'object') {
+ if (err) {
+ if (console.error) {
+ console.error(err);
+ }
+ } else if (console[name]) {
+ arrayEach(args, function (x) {
+ console[name](x);
+ });
+ }
+ }
+ })]));
+ });
+ }
- function forever(fn, cb) {
- var done = onlyOnce(cb || noop);
- var task = ensureAsync(fn);
+ var dir = consoleFunc('dir');
+
+ function during(test, iteratee, cb) {
+ cb = cb || noop;
+
+ var next = rest(function (err, args) {
+ if (err) {
+ cb(err);
+ } else {
+ args.push(check);
+ test.apply(this, args);
+ }
+ });
+
+ var check = function (err, truth) {
+ if (err) return cb(err);
+ if (!truth) return cb(null);
+ iteratee(next);
+ };
+
+ test(check);
+ }
+
+ function doDuring(iteratee, test, cb) {
+ var calls = 0;
+
+ during(function (next) {
+ if (calls++ < 1) return next(null, true);
+ test.apply(this, arguments);
+ }, iteratee, cb);
+ }
+
+ function whilst(test, iteratee, cb) {
+ cb = cb || noop;
+ if (!test()) return cb(null);
+ var next = rest(function (err, args) {
+ if (err) return cb(err);
+ if (test.apply(this, args)) return iteratee(next);
+ cb.apply(null, [null].concat(args));
+ });
+ iteratee(next);
+ }
+
+ function doWhilst(iteratee, test, cb) {
+ var calls = 0;
+ return whilst(function () {
+ return ++calls <= 1 || test.apply(this, arguments);
+ }, iteratee, cb);
+ }
+
+ function doUntil(iteratee, test, cb) {
+ return doWhilst(iteratee, function () {
+ return !test.apply(this, arguments);
+ }, cb);
+ }
+
+ function _withoutIndex(iteratee) {
+ return function (value, index, callback) {
+ return iteratee(value, callback);
+ };
+ }
+
+ function eachLimit(arr, limit, iteratee, cb) {
+ return _eachOfLimit(limit)(arr, _withoutIndex(iteratee), cb);
+ }
+
+ var each = doLimit(eachLimit, Infinity);
+
+ var eachSeries = doLimit(eachLimit, 1);
+
+ function ensureAsync(fn) {
+ return initialParams(function (args, callback) {
+ var sync = true;
+ args.push(function () {
+ var innerArgs = arguments;
+ if (sync) {
+ setImmediate$1(function () {
+ callback.apply(null, innerArgs);
+ });
+ } else {
+ callback.apply(null, innerArgs);
+ }
+ });
+ fn.apply(this, args);
+ sync = false;
+ });
+ }
+
+ function notId(v) {
+ return !v;
+ }
+
+ var everyLimit = _createTester(eachOfLimit, notId, notId);
+
+ var every = doLimit(everyLimit, Infinity);
+
+ var everySeries = doLimit(everyLimit, 1);
+
+ function _filter(eachfn, arr, iteratee, callback) {
+ var results = [];
+ eachfn(arr, function (x, index, callback) {
+ iteratee(x, function (err, v) {
+ if (err) {
+ callback(err);
+ } else {
+ if (v) {
+ results.push({ index: index, value: x });
+ }
+ callback();
+ }
+ });
+ }, function (err) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, arrayMap(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), baseProperty('value')));
+ }
+ });
+ }
+
+ function doParallelLimit(fn) {
+ return function (obj, limit, iteratee, callback) {
+ return fn(_eachOfLimit(limit), obj, iteratee, callback);
+ };
+ }
+
+ var filterLimit = doParallelLimit(_filter);
+
+ var filter = doLimit(filterLimit, Infinity);
+
+ var filterSeries = doLimit(filterLimit, 1);
+
+ function forever(fn, cb) {
+ var done = onlyOnce(cb || noop);
+ var task = ensureAsync(fn);
+
+ function next(err) {
+ if (err) return done(err);
+ task(next);
+ }
+ next();
+ }
- function next(err) {
- if (err) return done(err);
- task(next);
+ function iterator$1 (tasks) {
+ function makeCallback(index) {
+ function fn() {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments);
+ }
+ return fn.next();
+ }
+ fn.next = function () {
+ return index < tasks.length - 1 ? makeCallback(index + 1) : null;
+ };
+ return fn;
+ }
+ return makeCallback(0);
+ }
+
+ var log = consoleFunc('log');
+
+ function _asyncMap(eachfn, arr, iteratee, callback) {
+ callback = once(callback || noop);
+ arr = arr || [];
+ var results = isArrayLike(arr) || getIterator(arr) ? [] : {};
+ eachfn(arr, function (value, index, callback) {
+ iteratee(value, function (err, v) {
+ results[index] = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+
+ var mapLimit = doParallelLimit(_asyncMap);
+
+ var map = doLimit(mapLimit, Infinity);
+
+ var mapSeries = doLimit(mapLimit, 1);
+
+ /** `Object#toString` result references. */
+ var symbolTag$2 = '[object Symbol]';
+
+ /** Used for built-in method references. */
+ var objectProto$12 = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$4 = objectProto$12.toString;
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+ function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString$4.call(value) == symbolTag$2);
+ }
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY$1 = 1 / 0;
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto$1 = Symbol$1 ? Symbol$1.prototype : undefined;
+ var symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
+ /**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
}
- next();
- }
-
- function iterator (tasks) {
- function makeCallback(index) {
- function fn() {
- if (tasks.length) {
- tasks[index].apply(null, arguments);
- }
- return fn.next();
- }
- fn.next = function () {
- return index < tasks.length - 1 ? makeCallback(index + 1) : null;
- };
- return fn;
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return symbolToString ? symbolToString.call(value) : '';
}
- return makeCallback(0);
- }
-
- var log = consoleFunc('log');
-
- function _asyncMap(eachfn, arr, iterator, callback) {
- callback = once(callback || noop);
- arr = arr || [];
- var results = isArrayLike(arr) ? [] : {};
- eachfn(arr, function (value, index, callback) {
- iterator(value, function (err, v) {
- results[index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
+ }
+
+ /** Used to match property names within property paths. */
+ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
+
+ /** Used to match backslashes in property paths. */
+ var reEscapeChar = /\\(\\)?/g;
+
+ /**
+ * Converts `string` to a property path array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
+ */
+ function stringToPath(string) {
+ var result = [];
+ toString(string).replace(rePropName, function(match, number, quote, string) {
+ result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
- }
-
- var map = doParallel(_asyncMap);
-
- var mapLimit = doParallelLimit(_asyncMap);
-
- var mapSeries = doSeries(_asyncMap);
-
- /**
- * Checks if `value` is a global object.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {null|Object} Returns `value` if it's a global object, else `null`.
- */
- function checkGlobal(value) {
- return (value && value.Object === Object) ? value : null;
- }
-
- /** Used to determine if values are of the language type `Object`. */
- var objectTypes = {
- 'function': true,
- 'object': true
- };
-
- /** Detect free variable `exports`. */
- var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
-
- /** Detect free variable `module`. */
- var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
-
- /** Detect free variable `global` from Node.js. */
- var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
-
- /** Detect free variable `self`. */
- var freeSelf = checkGlobal(objectTypes[typeof self] && self);
-
- /** Detect free variable `window`. */
- var freeWindow = checkGlobal(objectTypes[typeof window] && window);
-
- /** Detect `this` as the global object. */
- var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
-
- /**
- * Used as a reference to the global object.
- *
- * The `this` value is used if it's the global object to avoid Greasemonkey's
- * restricted `window` object, otherwise the `window` object is used.
- */
- var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
-
- /** Built-in value references. */
- var Symbol = root.Symbol;
-
- /** `Object#toString` result references. */
- var symbolTag = '[object Symbol]';
-
- /** Used for built-in method references. */
- var objectProto$5 = Object.prototype;
-
- /**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objectToString$3 = objectProto$5.toString;
-
- /**
- * Checks if `value` is classified as a `Symbol` primitive or object.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isSymbol(Symbol.iterator);
- * // => true
- *
- * _.isSymbol('abc');
- * // => false
- */
- function isSymbol(value) {
- return typeof value == 'symbol' ||
- (isObjectLike(value) && objectToString$3.call(value) == symbolTag);
- }
-
- /** Used as references for various `Number` constants. */
- var INFINITY$1 = 1 / 0;
-
- /** Used to convert symbols to primitives and strings. */
- var symbolProto = Symbol ? Symbol.prototype : undefined;
- var symbolToString = Symbol ? symbolProto.toString : undefined;
- /**
- * Converts `value` to a string if it's not one. An empty string is returned
- * for `null` and `undefined` values. The sign of `-0` is preserved.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- * @example
- *
- * _.toString(null);
- * // => ''
- *
- * _.toString(-0);
- * // => '-0'
- *
- * _.toString([1, 2, 3]);
- * // => '1,2,3'
- */
- function toString(value) {
- // Exit early for strings to avoid a performance hit in some environments.
- if (typeof value == 'string') {
- return value;
+ return result;
}
- if (value == null) {
- return '';
- }
- if (isSymbol(value)) {
- return Symbol ? symbolToString.call(value) : '';
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
- }
-
- /** Used to match property names within property paths. */
- var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
-
- /** Used to match backslashes in property paths. */
- var reEscapeChar = /\\(\\)?/g;
-
- /**
- * Converts `string` to a property path array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the property path array.
- */
- function stringToPath(string) {
- var result = [];
- toString(string).replace(rePropName, function(match, number, quote, string) {
- result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
- });
- return result;
- }
-
- /**
- * The base implementation of `_.toPath` which only converts `value` to a
- * path if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Array} Returns the property path array.
- */
- function baseToPath(value) {
- return isArray(value) ? value : stringToPath(value);
- }
-
- var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
- var reIsPlainProp = /^\w*$/;
- /**
- * Checks if `value` is a property name and not a property path.
- *
- * @private
- * @param {*} value The value to check.
- * @param {Object} [object] The object to query keys on.
- * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
- */
- function isKey(value, object) {
- if (typeof value == 'number') {
- return true;
+
+ /**
+ * Casts `value` to a path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the cast property path array.
+ */
+ function baseCastPath(value) {
+ return isArray(value) ? value : stringToPath(value);
}
- return !isArray(value) &&
- (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
- (object != null && value in Object(object)));
- }
-
- /**
- * Gets the last element of `array`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to query.
- * @returns {*} Returns the last element of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- */
- function last(array) {
- var length = array ? array.length : 0;
- return length ? array[length - 1] : undefined;
- }
-
- /**
- * The base implementation of `_.slice` without an iteratee call guard.
- *
- * @private
- * @param {Array} array The array to slice.
- * @param {number} [start=0] The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the slice of `array`.
- */
- function baseSlice(array, start, end) {
- var index = -1,
- length = array.length;
-
- if (start < 0) {
- start = -start > length ? 0 : (length + start);
- }
- end = end > length ? length : end;
- if (end < 0) {
- end += length;
- }
- length = start > end ? 0 : ((end - start) >>> 0);
- start >>>= 0;
-
- var result = Array(length);
- while (++index < length) {
- result[index] = array[index + start];
- }
- return result;
- }
-
- /**
- * The base implementation of `_.get` without support for default values.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @returns {*} Returns the resolved value.
- */
- function baseGet(object, path) {
- path = isKey(path, object) ? [path + ''] : baseToPath(path);
-
- var index = 0,
- length = path.length;
-
- while (object != null && index < length) {
- object = object[path[index++]];
- }
- return (index && index == length) ? object : undefined;
- }
-
- /**
- * Gets the value at `path` of `object`. If the resolved value is
- * `undefined` the `defaultValue` is used in its place.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
- *
- * _.get(object, 'a[0].b.c');
- * // => 3
- *
- * _.get(object, ['a', '0', 'b', 'c']);
- * // => 3
- *
- * _.get(object, 'a.b.c', 'default');
- * // => 'default'
- */
- function get(object, path, defaultValue) {
- var result = object == null ? undefined : baseGet(object, path);
- return result === undefined ? defaultValue : result;
- }
-
- /**
- * Gets the parent value at `path` of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array} path The path to get the parent value of.
- * @returns {*} Returns the parent value.
- */
- function parent(object, path) {
- return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
- }
-
- /**
- * Checks if `path` exists on `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @param {Function} hasFunc The function to check properties.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- */
- function hasPath(object, path, hasFunc) {
- if (object == null) {
- return false;
- }
- var result = hasFunc(object, path);
- if (!result && !isKey(path)) {
- path = baseToPath(path);
- object = parent(object, path);
- if (object != null) {
- path = last(path);
- result = hasFunc(object, path);
+
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
+ var reIsPlainProp = /^\w*$/;
+ /**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */
+ function isKey(value, object) {
+ if (typeof value == 'number') {
+ return true;
}
+ return !isArray(value) &&
+ (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object)));
}
- var length = object ? object.length : undefined;
- return result || (
- !!length && isLength(length) && isIndex(path, length) &&
- (isArray(object) || isString(object) || isArguments(object))
- );
- }
-
- /**
- * Checks if `path` is a direct property of `object`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- * @example
- *
- * var object = { 'a': { 'b': { 'c': 3 } } };
- * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
- *
- * _.has(object, 'a');
- * // => true
- *
- * _.has(object, 'a.b.c');
- * // => true
- *
- * _.has(object, ['a', 'b', 'c']);
- * // => true
- *
- * _.has(other, 'a');
- * // => false
- */
- function has(object, path) {
- return hasPath(object, path, baseHas);
- }
-
- function memoize(fn, hasher) {
- var memo = Object.create(null);
- var queues = Object.create(null);
- hasher = hasher || identity;
- var memoized = rest(function memoized(args) {
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (has(memo, key)) {
- setImmediate$1(function () {
- callback.apply(null, memo[key]);
- });
- } else if (has(queues, key)) {
- queues[key].push(callback);
- } else {
- queues[key] = [callback];
- fn.apply(null, args.concat([rest(function (args) {
- memo[key] = args;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, args);
- }
- })]));
- }
- });
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
- }
-
- var nexTick = typeof process === 'object' && typeof process.nextTick === 'function' ? process.nextTick : setImmediate$1;
-
- function _parallel(eachfn, tasks, callback) {
- callback = callback || noop;
- var results = isArrayLike(tasks) ? [] : {};
-
- eachfn(tasks, function (task, key, callback) {
- task(rest(function (err, args) {
- if (args.length <= 1) {
- args = args[0];
- }
- results[key] = args;
- callback(err);
- }));
- }, function (err) {
- callback(err, results);
- });
- }
- function parallel(tasks, cb) {
- return _parallel(eachOf, tasks, cb);
- }
+ /**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+ function last(array) {
+ var length = array ? array.length : 0;
+ return length ? array[length - 1] : undefined;
+ }
- function parallelLimit(tasks, limit, cb) {
- return _parallel(_eachOfLimit(limit), tasks, cb);
- }
+ /**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseSlice(array, start, end) {
+ var index = -1,
+ length = array.length;
- function queue (worker, concurrency) {
- return queue$1(function (items, cb) {
- worker(items[0], cb);
- }, concurrency, 1);
- }
+ if (start < 0) {
+ start = -start > length ? 0 : (length + start);
+ }
+ end = end > length ? length : end;
+ if (end < 0) {
+ end += length;
+ }
+ length = start > end ? 0 : ((end - start) >>> 0);
+ start >>>= 0;
- function priorityQueue (worker, concurrency) {
- function _compareTasks(a, b) {
- return a.priority - b.priority;
+ var result = Array(length);
+ while (++index < length) {
+ result[index] = array[index + start];
}
+ return result;
+ }
- function _binarySearch(sequence, item, compare) {
- var beg = -1,
- end = sequence.length - 1;
- while (beg < end) {
- var mid = beg + (end - beg + 1 >>> 1);
- if (compare(item, sequence[mid]) >= 0) {
- beg = mid;
- } else {
- end = mid - 1;
- }
- }
- return beg;
+ /**
+ * The base implementation of `_.get` without support for default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseGet(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseCastPath(path);
+
+ var index = 0,
+ length = path.length;
+
+ while (object != null && index < length) {
+ object = object[path[index++]];
}
+ return (index && index == length) ? object : undefined;
+ }
- function _insert(q, data, priority, callback) {
- if (callback != null && typeof callback !== 'function') {
- throw new Error('task callback must be a function');
- }
- q.started = true;
- if (!isArray(data)) {
- data = [data];
- }
- if (data.length === 0) {
- // call drain immediately if there are no tasks
- return setImmediate$1(function () {
- q.drain();
- });
- }
- arrayEach(data, function (task) {
- var item = {
- data: task,
- priority: priority,
- callback: typeof callback === 'function' ? callback : noop
- };
-
- q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
-
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- setImmediate$1(q.process);
- });
+ /**
+ * Gets the value at `path` of `object`. If the resolved value is
+ * `undefined` the `defaultValue` is used in its place.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.get(object, 'a[0].b.c');
+ * // => 3
+ *
+ * _.get(object, ['a', '0', 'b', 'c']);
+ * // => 3
+ *
+ * _.get(object, 'a.b.c', 'default');
+ * // => 'default'
+ */
+ function get(object, path, defaultValue) {
+ var result = object == null ? undefined : baseGet(object, path);
+ return result === undefined ? defaultValue : result;
+ }
+
+ /**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */
+ function parent(object, path) {
+ return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
+ }
+
+ /**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+ function hasPath(object, path, hasFunc) {
+ if (object == null) {
+ return false;
+ }
+ var result = hasFunc(object, path);
+ if (!result && !isKey(path)) {
+ path = baseCastPath(path);
+ object = parent(object, path);
+ if (object != null) {
+ path = last(path);
+ result = hasFunc(object, path);
+ }
}
+ var length = object ? object.length : undefined;
+ return result || (
+ !!length && isLength(length) && isIndex(path, length) &&
+ (isArray(object) || isString(object) || isArguments(object))
+ );
+ }
- // Start with a normal queue
- var q = queue(worker, concurrency);
+ /**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b.c');
+ * // => true
+ *
+ * _.has(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+ function has(object, path) {
+ return hasPath(object, path, baseHas);
+ }
- // Override push to accept second parameter representing priority
- q.push = function (data, priority, callback) {
- _insert(q, data, priority, callback);
- };
+ function memoize(fn, hasher) {
+ var memo = Object.create(null);
+ var queues = Object.create(null);
+ hasher = hasher || identity;
+ var memoized = initialParams(function memoized(args, callback) {
+ var key = hasher.apply(null, args);
+ if (has(memo, key)) {
+ setImmediate$1(function () {
+ callback.apply(null, memo[key]);
+ });
+ } else if (has(queues, key)) {
+ queues[key].push(callback);
+ } else {
+ queues[key] = [callback];
+ fn.apply(null, args.concat([rest(function (args) {
+ memo[key] = args;
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, args);
+ }
+ })]));
+ }
+ });
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
+ }
- // Remove unshift function
- delete q.unshift;
+ function _parallel(eachfn, tasks, callback) {
+ callback = callback || noop;
+ var results = isArrayLike(tasks) ? [] : {};
+
+ eachfn(tasks, function (task, key, callback) {
+ task(rest(function (err, args) {
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[key] = args;
+ callback(err);
+ }));
+ }, function (err) {
+ callback(err, results);
+ });
+ }
- return q;
- }
+ function parallelLimit(tasks, limit, cb) {
+ return _parallel(_eachOfLimit(limit), tasks, cb);
+ }
- var slice = Array.prototype.slice;
+ var parallel = doLimit(parallelLimit, Infinity);
- function reduceRight(arr, memo, iterator, cb) {
- var reversed = slice.call(arr).reverse();
- reduce(reversed, memo, iterator, cb);
- }
+ function queue$1 (worker, concurrency) {
+ return queue(function (items, cb) {
+ worker(items[0], cb);
+ }, concurrency, 1);
+ }
- function reject$1(eachfn, arr, iterator, callback) {
- _filter(eachfn, arr, function (value, cb) {
- iterator(value, function (err, v) {
- if (err) {
- cb(err);
- } else {
- cb(null, !v);
- }
- });
- }, callback);
- }
+ function priorityQueue (worker, concurrency) {
+ function _compareTasks(a, b) {
+ return a.priority - b.priority;
+ }
- var reject = doParallel(reject$1);
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1;
+ while (beg < end) {
+ var mid = beg + (end - beg + 1 >>> 1);
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return beg;
+ }
- var rejectLimit = doParallelLimit(reject$1);
+ function _insert(q, data, priority, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!isArray(data)) {
+ data = [data];
+ }
+ if (data.length === 0) {
+ // call drain immediately if there are no tasks
+ return setImmediate$1(function () {
+ q.drain();
+ });
+ }
+ arrayEach(data, function (task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : noop
+ };
+
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ if (q.tasks.length <= q.concurrency - q.buffer) {
+ q.unsaturated();
+ }
+ setImmediate$1(q.process);
+ });
+ }
- var rejectSeries = doSeries(reject$1);
+ // Start with a normal queue
+ var q = queue$1(worker, concurrency);
- function series(tasks, cb) {
- return _parallel(eachOfSeries, tasks, cb);
- }
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback);
+ };
- function retry(times, task, callback) {
- var DEFAULT_TIMES = 5;
- var DEFAULT_INTERVAL = 0;
+ // Remove unshift function
+ delete q.unshift;
- var attempts = [];
+ return q;
+ }
- var opts = {
- times: DEFAULT_TIMES,
- interval: DEFAULT_INTERVAL
- };
+ /**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseEach(eachFunc, fromRight) {
+ return function(collection, iteratee) {
+ if (collection == null) {
+ return collection;
+ }
+ if (!isArrayLike(collection)) {
+ return eachFunc(collection, iteratee);
+ }
+ var length = collection.length,
+ index = fromRight ? length : -1,
+ iterable = Object(collection);
- function parseTimes(acc, t) {
- if (typeof t === 'number') {
- acc.times = parseInt(t, 10) || DEFAULT_TIMES;
- } else if (typeof t === 'object') {
- acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
- acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
- } else {
- throw new Error('Unsupported argument type for \'times\': ' + typeof t);
+ while ((fromRight ? index-- : ++index < length)) {
+ if (iteratee(iterable[index], index, iterable) === false) {
+ break;
}
- }
+ }
+ return collection;
+ };
+ }
- var length = arguments.length;
- if (length < 1 || length > 3) {
- throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
- } else if (length <= 2 && typeof times === 'function') {
- callback = task;
- task = times;
- }
- if (typeof times !== 'function') {
- parseTimes(opts, times);
- }
- opts.callback = callback;
- opts.task = task;
-
- function wrappedTask(wrappedCallback, wrappedResults) {
- function retryAttempt(task, finalAttempt) {
- return function (seriesCallback) {
- task(function (err, result) {
- seriesCallback(!err || finalAttempt, {
- err: err,
- result: result
- });
- }, wrappedResults);
- };
- }
+ /**
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */
+ var baseEach = createBaseEach(baseForOwn);
+
+ /**
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
+ * for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @example
+ *
+ * _([1, 2]).forEach(function(value) {
+ * console.log(value);
+ * });
+ * // => logs `1` then `2`
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forEach(collection, iteratee) {
+ return (typeof iteratee == 'function' && isArray(collection))
+ ? arrayEach(collection, iteratee)
+ : baseEach(collection, baseCastFunction(iteratee));
+ }
- function retryInterval(interval) {
- return function (seriesCallback) {
- setTimeout(function () {
- seriesCallback(null);
- }, interval);
- };
- }
+ function race(tasks, cb) {
+ cb = once(cb || noop);
+ if (!isArray(tasks)) return cb(new TypeError('First argument to race must be an array of functions'));
+ if (!tasks.length) return cb();
+ forEach(tasks, function (task) {
+ task(cb);
+ });
+ }
- while (opts.times) {
+ var slice = Array.prototype.slice;
- var finalAttempt = !(opts.times -= 1);
- attempts.push(retryAttempt(opts.task, finalAttempt));
- if (!finalAttempt && opts.interval > 0) {
- attempts.push(retryInterval(opts.interval));
- }
- }
+ function reduceRight(arr, memo, iteratee, cb) {
+ var reversed = slice.call(arr).reverse();
+ reduce(reversed, memo, iteratee, cb);
+ }
- series(attempts, function (done, data) {
- data = data[data.length - 1];
- (wrappedCallback || opts.callback)(data.err, data.result);
- });
- }
+ function reject$1(eachfn, arr, iteratee, callback) {
+ _filter(eachfn, arr, function (value, cb) {
+ iteratee(value, function (err, v) {
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, !v);
+ }
+ });
+ }, callback);
+ }
- // If a callback is passed, run this as a controll flow
- return opts.callback ? wrappedTask() : wrappedTask;
- }
+ var rejectLimit = doParallelLimit(reject$1);
- var some = _createTester(eachOf, Boolean, identity);
+ var reject = doLimit(rejectLimit, Infinity);
- var someLimit = _createTester(eachOfLimit, Boolean, identity);
+ var rejectSeries = doLimit(rejectLimit, 1);
- function sortBy(arr, iterator, cb) {
- map(arr, function (x, cb) {
- iterator(x, function (err, criteria) {
- if (err) return cb(err);
- cb(null, { value: x, criteria: criteria });
- });
- }, function (err, results) {
- if (err) return cb(err);
- cb(null, arrayMap(results.sort(comparator), baseProperty('value')));
- });
+ function series(tasks, cb) {
+ return _parallel(eachOfSeries, tasks, cb);
+ }
- function comparator(left, right) {
- var a = left.criteria,
- b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }
- }
-
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeCeil = Math.ceil;
- var nativeMax$2 = Math.max;
- /**
- * The base implementation of `_.range` and `_.rangeRight` which doesn't
- * coerce arguments to numbers.
- *
- * @private
- * @param {number} start The start of the range.
- * @param {number} end The end of the range.
- * @param {number} step The value to increment or decrement by.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Array} Returns the new array of numbers.
- */
- function baseRange(start, end, step, fromRight) {
- var index = -1,
- length = nativeMax$2(nativeCeil((end - start) / (step || 1)), 0),
- result = Array(length);
-
- while (length--) {
- result[fromRight ? length : ++index] = start;
- start += step;
- }
- return result;
- }
-
- function times (count, iterator, callback) {
- map(baseRange(0, count, 1), iterator, callback);
- }
-
- function timeLimit(count, limit, iterator, cb) {
- return mapLimit(baseRange(0, count, 1), limit, iterator, cb);
- }
-
- function timesSeries (count, iterator, callback) {
- mapSeries(baseRange(0, count, 1), iterator, callback);
- }
-
- function transform(arr, memo, iterator, callback) {
- if (arguments.length === 3) {
- callback = iterator;
- iterator = memo;
- memo = isArray(arr) ? [] : {};
- }
+ function retry(times, task, callback) {
+ var DEFAULT_TIMES = 5;
+ var DEFAULT_INTERVAL = 0;
+
+ var opts = {
+ times: DEFAULT_TIMES,
+ interval: DEFAULT_INTERVAL
+ };
+
+ function parseTimes(acc, t) {
+ if (typeof t === 'object') {
+ acc.times = +t.times || DEFAULT_TIMES;
+ acc.interval = +t.interval || DEFAULT_INTERVAL;
+ } else if (typeof t === 'number' || typeof t === 'string') {
+ acc.times = +t || DEFAULT_TIMES;
+ } else {
+ throw new Error("Invalid arguments for async.retry");
+ }
+ }
- eachOf(arr, function (v, k, cb) {
- iterator(memo, v, k, cb);
- }, function (err) {
- callback(err, memo);
- });
- }
+ if (arguments.length < 3 && typeof times === 'function') {
+ callback = task || noop;
+ task = times;
+ } else {
+ parseTimes(opts, times);
+ callback = callback || noop;
+ }
- function unmemoize(fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- }
-
- function until(test, iterator, cb) {
- return whilst(function () {
- return !test.apply(this, arguments);
- }, iterator, cb);
- }
-
- function waterfall (tasks, cb) {
- cb = once(cb || noop);
- if (!isArray(tasks)) return cb(new Error('First argument to waterfall must be an array of functions'));
- if (!tasks.length) return cb();
-
- function wrapIterator(iterator) {
- return rest(function (err, args) {
- if (err) {
- cb.apply(null, [err].concat(args));
- } else {
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- } else {
- args.push(cb);
- }
- ensureAsync(iterator).apply(null, args);
- }
- });
+ if (typeof task !== 'function') {
+ throw new Error("Invalid arguments for async.retry");
+ }
+
+ var attempts = [];
+ while (opts.times) {
+ var isFinalAttempt = !(opts.times -= 1);
+ attempts.push(retryAttempt(isFinalAttempt));
+ if (!isFinalAttempt && opts.interval > 0) {
+ attempts.push(retryInterval(opts.interval));
+ }
+ }
+
+ series(attempts, function (done, data) {
+ data = data[data.length - 1];
+ callback(data.err, data.result);
+ });
+
+ function retryAttempt(isFinalAttempt) {
+ return function (seriesCallback) {
+ task(function (err, result) {
+ seriesCallback(!err || isFinalAttempt, {
+ err: err,
+ result: result
+ });
+ });
+ };
+ }
+
+ function retryInterval(interval) {
+ return function (seriesCallback) {
+ setTimeout(function () {
+ seriesCallback(null);
+ }, interval);
+ };
+ }
+ }
+
+ function retryable (opts, task) {
+ if (!task) {
+ task = opts;
+ opts = null;
+ }
+ return initialParams(function (args, callback) {
+ function taskFn(cb) {
+ task.apply(null, args.concat([cb]));
+ }
+
+ if (opts) retry(opts, taskFn, callback);else retry(taskFn, callback);
+ });
+ }
+
+ var someLimit = _createTester(eachOfLimit, Boolean, identity);
+
+ var some = doLimit(someLimit, Infinity);
+
+ var someSeries = doLimit(someLimit, 1);
+
+ function sortBy(arr, iteratee, cb) {
+ map(arr, function (x, cb) {
+ iteratee(x, function (err, criteria) {
+ if (err) return cb(err);
+ cb(null, { value: x, criteria: criteria });
+ });
+ }, function (err, results) {
+ if (err) return cb(err);
+ cb(null, arrayMap(results.sort(comparator), baseProperty('value')));
+ });
+
+ function comparator(left, right) {
+ var a = left.criteria,
+ b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }
+ }
+
+ function timeout(asyncFn, miliseconds) {
+ var originalCallback, timer;
+ var timedOut = false;
+
+ function injectedCallback() {
+ if (!timedOut) {
+ originalCallback.apply(null, arguments);
+ clearTimeout(timer);
+ }
+ }
+
+ function timeoutCallback() {
+ var error = new Error('Callback function timed out.');
+ error.code = 'ETIMEDOUT';
+ timedOut = true;
+ originalCallback(error);
+ }
+
+ return initialParams(function (args, origCallback) {
+ originalCallback = origCallback;
+ // setup timer and call original function
+ timer = setTimeout(timeoutCallback, miliseconds);
+ asyncFn.apply(null, args.concat(injectedCallback));
+ });
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil;
+ var nativeMax$2 = Math.max;
+ /**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the new array of numbers.
+ */
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax$2(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
+
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
}
- wrapIterator(iterator(tasks))();
- }
-
- var index = {
- applyEach: applyEach,
- applyEachSeries: applyEachSeries,
- apply: apply,
- asyncify: asyncify,
- auto: auto,
- cargo: cargo,
- compose: compose,
- concat: concat,
- concatSeries: concatSeries,
- constant: constant,
- detect: detect,
- detectLimit: detectLimit,
- detectSeries: detectSeries,
- dir: dir,
- doDuring: doDuring,
- doUntil: doUntil,
- doWhilst: doWhilst,
- during: during,
- each: each,
- eachLimit: eachLimit,
- eachOf: eachOf,
- eachOfLimit: eachOfLimit,
- eachOfSeries: eachOfSeries,
- eachSeries: eachSeries,
- ensureAsync: ensureAsync,
- every: every,
- everyLimit: everyLimit,
- filter: filter,
- filterLimit: filterLimit,
- filterSeries: filterSeries,
- forever: forever,
- iterator: iterator,
- log: log,
- map: map,
- mapLimit: mapLimit,
- mapSeries: mapSeries,
- memoize: memoize,
- nextTick: nexTick,
- parallel: parallel,
- parallelLimit: parallelLimit,
- priorityQueue: priorityQueue,
- queue: queue,
- reduce: reduce,
- reduceRight: reduceRight,
- reject: reject,
- rejectLimit: rejectLimit,
- rejectSeries: rejectSeries,
- retry: retry,
- seq: seq,
- series: series,
- setImmediate: setImmediate$1,
- some: some,
- someLimit: someLimit,
- sortBy: sortBy,
- times: times,
- timesLimit: timeLimit,
- timesSeries: timesSeries,
- transform: transform,
- unmemoize: unmemoize,
- until: until,
- waterfall: waterfall,
- whilst: whilst,
-
- // aliases
- all: every,
- any: some,
- forEach: each,
- forEachSeries: eachSeries,
- forEachLimit: eachLimit,
- forEachOf: eachOf,
- forEachOfSeries: eachOfSeries,
- forEachOfLimit: eachOfLimit,
- inject: reduce,
- foldl: reduce,
- foldr: reduceRight,
- select: filter,
- selectLimit: filterLimit,
- selectSeries: filterSeries,
- wrapSync: asyncify
- };
-
- exports['default'] = index;
- exports.applyEach = applyEach;
- exports.applyEachSeries = applyEachSeries;
- exports.apply = apply;
- exports.asyncify = asyncify;
- exports.auto = auto;
- exports.cargo = cargo;
- exports.compose = compose;
- exports.concat = concat;
- exports.concatSeries = concatSeries;
- exports.constant = constant;
- exports.detect = detect;
- exports.detectLimit = detectLimit;
- exports.detectSeries = detectSeries;
- exports.dir = dir;
- exports.doDuring = doDuring;
- exports.doUntil = doUntil;
- exports.doWhilst = doWhilst;
- exports.during = during;
- exports.each = each;
- exports.eachLimit = eachLimit;
- exports.eachOf = eachOf;
- exports.eachOfLimit = eachOfLimit;
- exports.eachOfSeries = eachOfSeries;
- exports.eachSeries = eachSeries;
- exports.ensureAsync = ensureAsync;
- exports.every = every;
- exports.everyLimit = everyLimit;
- exports.filter = filter;
- exports.filterLimit = filterLimit;
- exports.filterSeries = filterSeries;
- exports.forever = forever;
- exports.iterator = iterator;
- exports.log = log;
- exports.map = map;
- exports.mapLimit = mapLimit;
- exports.mapSeries = mapSeries;
- exports.memoize = memoize;
- exports.nextTick = nexTick;
- exports.parallel = parallel;
- exports.parallelLimit = parallelLimit;
- exports.priorityQueue = priorityQueue;
- exports.queue = queue;
- exports.reduce = reduce;
- exports.reduceRight = reduceRight;
- exports.reject = reject;
- exports.rejectLimit = rejectLimit;
- exports.rejectSeries = rejectSeries;
- exports.retry = retry;
- exports.seq = seq;
- exports.series = series;
- exports.setImmediate = setImmediate$1;
- exports.some = some;
- exports.someLimit = someLimit;
- exports.sortBy = sortBy;
- exports.times = times;
- exports.timesLimit = timeLimit;
- exports.timesSeries = timesSeries;
- exports.transform = transform;
- exports.unmemoize = unmemoize;
- exports.until = until;
- exports.waterfall = waterfall;
- exports.whilst = whilst;
- exports.all = every;
- exports.any = some;
- exports.forEach = each;
- exports.forEachSeries = eachSeries;
- exports.forEachLimit = eachLimit;
- exports.forEachOf = eachOf;
- exports.forEachOfSeries = eachOfSeries;
- exports.forEachOfLimit = eachOfLimit;
- exports.inject = reduce;
- exports.foldl = reduce;
- exports.foldr = reduceRight;
- exports.select = filter;
- exports.selectLimit = filterLimit;
- exports.selectSeries = filterSeries;
- exports.wrapSync = asyncify;
+ return result;
+ }
+
+ function timeLimit(count, limit, iteratee, cb) {
+ return mapLimit(baseRange(0, count, 1), limit, iteratee, cb);
+ }
+
+ var times = doLimit(timeLimit, Infinity);
+
+ var timesSeries = doLimit(timeLimit, 1);
+
+ function transform(arr, memo, iteratee, callback) {
+ if (arguments.length === 3) {
+ callback = iteratee;
+ iteratee = memo;
+ memo = isArray(arr) ? [] : {};
+ }
+
+ eachOf(arr, function (v, k, cb) {
+ iteratee(memo, v, k, cb);
+ }, function (err) {
+ callback(err, memo);
+ });
+ }
+
+ function unmemoize(fn) {
+ return function () {
+ return (fn.unmemoized || fn).apply(null, arguments);
+ };
+ }
+
+ function until(test, iteratee, cb) {
+ return whilst(function () {
+ return !test.apply(this, arguments);
+ }, iteratee, cb);
+ }
+
+ function waterfall (tasks, cb) {
+ cb = once(cb || noop);
+ if (!isArray(tasks)) return cb(new Error('First argument to waterfall must be an array of functions'));
+ if (!tasks.length) return cb();
+ var taskIndex = 0;
+
+ function nextTask(args) {
+ if (taskIndex === tasks.length) {
+ return cb.apply(null, [null].concat(args));
+ }
+
+ var taskCallback = onlyOnce(rest(function (err, args) {
+ if (err) {
+ return cb.apply(null, [err].concat(args));
+ }
+ nextTask(args);
+ }));
+
+ args.push(taskCallback);
+
+ var task = tasks[taskIndex++];
+ task.apply(null, args);
+ }
+
+ nextTask([]);
+ }
+
+ var index = {
+ applyEach: applyEach,
+ applyEachSeries: applyEachSeries,
+ apply: apply$1,
+ asyncify: asyncify,
+ auto: auto,
+ autoInject: autoInject,
+ cargo: cargo,
+ compose: compose,
+ concat: concat,
+ concatSeries: concatSeries,
+ constant: constant$1,
+ detect: detect,
+ detectLimit: detectLimit,
+ detectSeries: detectSeries,
+ dir: dir,
+ doDuring: doDuring,
+ doUntil: doUntil,
+ doWhilst: doWhilst,
+ during: during,
+ each: each,
+ eachLimit: eachLimit,
+ eachOf: eachOf,
+ eachOfLimit: eachOfLimit,
+ eachOfSeries: eachOfSeries,
+ eachSeries: eachSeries,
+ ensureAsync: ensureAsync,
+ every: every,
+ everyLimit: everyLimit,
+ everySeries: everySeries,
+ filter: filter,
+ filterLimit: filterLimit,
+ filterSeries: filterSeries,
+ forever: forever,
+ iterator: iterator$1,
+ log: log,
+ map: map,
+ mapLimit: mapLimit,
+ mapSeries: mapSeries,
+ memoize: memoize,
+ nextTick: setImmediate$1,
+ parallel: parallel,
+ parallelLimit: parallelLimit,
+ priorityQueue: priorityQueue,
+ queue: queue$1,
+ race: race,
+ reduce: reduce,
+ reduceRight: reduceRight,
+ reject: reject,
+ rejectLimit: rejectLimit,
+ rejectSeries: rejectSeries,
+ retry: retry,
+ retryable: retryable,
+ seq: seq,
+ series: series,
+ setImmediate: setImmediate$1,
+ some: some,
+ someLimit: someLimit,
+ someSeries: someSeries,
+ sortBy: sortBy,
+ timeout: timeout,
+ times: times,
+ timesLimit: timeLimit,
+ timesSeries: timesSeries,
+ transform: transform,
+ unmemoize: unmemoize,
+ until: until,
+ waterfall: waterfall,
+ whilst: whilst,
+
+ // aliases
+ all: every,
+ any: some,
+ forEach: each,
+ forEachSeries: eachSeries,
+ forEachLimit: eachLimit,
+ forEachOf: eachOf,
+ forEachOfSeries: eachOfSeries,
+ forEachOfLimit: eachOfLimit,
+ inject: reduce,
+ foldl: reduce,
+ foldr: reduceRight,
+ select: filter,
+ selectLimit: filterLimit,
+ selectSeries: filterSeries,
+ wrapSync: asyncify
+ };
+
+ exports['default'] = index;
+ exports.applyEach = applyEach;
+ exports.applyEachSeries = applyEachSeries;
+ exports.apply = apply$1;
+ exports.asyncify = asyncify;
+ exports.auto = auto;
+ exports.autoInject = autoInject;
+ exports.cargo = cargo;
+ exports.compose = compose;
+ exports.concat = concat;
+ exports.concatSeries = concatSeries;
+ exports.constant = constant$1;
+ exports.detect = detect;
+ exports.detectLimit = detectLimit;
+ exports.detectSeries = detectSeries;
+ exports.dir = dir;
+ exports.doDuring = doDuring;
+ exports.doUntil = doUntil;
+ exports.doWhilst = doWhilst;
+ exports.during = during;
+ exports.each = each;
+ exports.eachLimit = eachLimit;
+ exports.eachOf = eachOf;
+ exports.eachOfLimit = eachOfLimit;
+ exports.eachOfSeries = eachOfSeries;
+ exports.eachSeries = eachSeries;
+ exports.ensureAsync = ensureAsync;
+ exports.every = every;
+ exports.everyLimit = everyLimit;
+ exports.everySeries = everySeries;
+ exports.filter = filter;
+ exports.filterLimit = filterLimit;
+ exports.filterSeries = filterSeries;
+ exports.forever = forever;
+ exports.iterator = iterator$1;
+ exports.log = log;
+ exports.map = map;
+ exports.mapLimit = mapLimit;
+ exports.mapSeries = mapSeries;
+ exports.memoize = memoize;
+ exports.nextTick = setImmediate$1;
+ exports.parallel = parallel;
+ exports.parallelLimit = parallelLimit;
+ exports.priorityQueue = priorityQueue;
+ exports.queue = queue$1;
+ exports.race = race;
+ exports.reduce = reduce;
+ exports.reduceRight = reduceRight;
+ exports.reject = reject;
+ exports.rejectLimit = rejectLimit;
+ exports.rejectSeries = rejectSeries;
+ exports.retry = retry;
+ exports.retryable = retryable;
+ exports.seq = seq;
+ exports.series = series;
+ exports.setImmediate = setImmediate$1;
+ exports.some = some;
+ exports.someLimit = someLimit;
+ exports.someSeries = someSeries;
+ exports.sortBy = sortBy;
+ exports.timeout = timeout;
+ exports.times = times;
+ exports.timesLimit = timeLimit;
+ exports.timesSeries = timesSeries;
+ exports.transform = transform;
+ exports.unmemoize = unmemoize;
+ exports.until = until;
+ exports.waterfall = waterfall;
+ exports.whilst = whilst;
+ exports.all = every;
+ exports.allLimit = everyLimit;
+ exports.allSeries = everySeries;
+ exports.any = some;
+ exports.anyLimit = someLimit;
+ exports.anySeries = someSeries;
+ exports.find = detect;
+ exports.findLimit = detectLimit;
+ exports.findSeries = detectSeries;
+ exports.forEach = each;
+ exports.forEachSeries = eachSeries;
+ exports.forEachLimit = eachLimit;
+ exports.forEachOf = eachOf;
+ exports.forEachOfSeries = eachOfSeries;
+ exports.forEachOfLimit = eachOfLimit;
+ exports.inject = reduce;
+ exports.foldl = reduce;
+ exports.foldr = reduceRight;
+ exports.select = filter;
+ exports.selectLimit = filterLimit;
+ exports.selectSeries = filterSeries;
+ exports.wrapSync = asyncify;
})); \ No newline at end of file
diff --git a/dist/async.min.js b/dist/async.min.js
index 2915a67..9e8eaf4 100644
--- a/dist/async.min.js
+++ b/dist/async.min.js
@@ -1,2 +1,2 @@
-!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.async={})}(this,function(n){"use strict";function t(n,t,r){var e=r.length;switch(e){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function r(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function e(n){var t=r(n)?nt.call(n):"";return t==Yn||t==Zn}function u(n){if(r(n)){var t=e(n.valueOf)?n.valueOf():n;n=r(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=n.replace(rt,"");var u=ut.test(n);return u||it.test(n)?ot(n.slice(2),u?2:8):et.test(n)?tt:+n}function i(n){if(!n)return 0===n?n:0;if(n=u(n),n===ct||n===-ct){var t=0>n?-1:1;return t*ft}var r=n%1;return n===n?r?n-r:n:0}function o(n,r){if("function"!=typeof n)throw new TypeError(at);return r=lt(void 0===r?n.length-1:i(r),0),function(){for(var e=arguments,u=-1,i=lt(e.length-r,0),o=Array(i);++u<i;)o[u]=e[r+u];switch(r){case 0:return n.call(this,o);case 1:return n.call(this,e[0],o);case 2:return n.call(this,e[0],e[1],o)}var c=Array(r+1);for(u=-1;++u<r;)c[u]=e[u];return c[r]=o,t(n,this,c)}}function c(n){return o(function(t,r){var e=o(function(r){var e=this,u=r.pop();return n(t,function(n,t,u){n.apply(e,r.concat([u]))},u)});return r.length?e.apply(this,r):e})}function f(n,t){var r;if("function"!=typeof t)throw new TypeError(st);return n=i(n),function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=void 0),r}}function a(n){return f(2,n)}function l(){}function s(n){return function(t){return null==t?void 0:t[n]}}function p(n){return"number"==typeof n&&n>-1&&n%1==0&&yt>=n}function y(n){return null!=n&&!("function"==typeof n&&e(n))&&p(pt(n))}function h(n,t){return vt.call(n,t)||"object"==typeof n&&t in n&&null===mt(n)}function v(n){return dt(Object(n))}function m(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function d(n){return!!n&&"object"==typeof n}function g(n){return d(n)&&y(n)}function b(n){return g(n)&&kt.call(n,"callee")&&(!jt.call(n,"callee")||wt.call(n)==gt)}function k(n){return"string"==typeof n||!St(n)&&d(n)&&Lt.call(n)==Ot}function w(n){var t=n?n.length:void 0;return p(t)&&(St(n)||k(n)||b(n))?m(t,String):null}function j(n,t){return n="number"==typeof n||At.test(n)?+n:-1,t=null==t?xt:t,n>-1&&n%1==0&&t>n}function S(n){var t=n&&n.constructor,r="function"==typeof t&&t.prototype||Tt;return n===r}function O(n){var t=S(n);if(!t&&!y(n))return v(n);var r=w(n),e=!!r,u=r||[],i=u.length;for(var o in n)!h(n,o)||e&&("length"==o||j(o,i))||t&&"constructor"==o||u.push(o);return u}function E(n){var t,r=-1;if(y(n))return t=n.length,function(){return r++,t>r?r:null};var e=O(n);return t=e.length,function(){return r++,t>r?e[r]:null}}function L(n){return function(){if(null===n)throw new Error("Callback was already called.");n.apply(this,arguments),n=null}}function x(n,t,r){function e(n){o--,n?r(n):null===u&&0>=o&&r(null)}r=a(r||l),n=n||[];for(var u,i=E(n),o=0;null!=(u=i());)o+=1,t(n[u],u,L(e));0===o&&r(null)}function A(n,t,r){function e(){var o=!0;return null===i?r(null):(t(n[i],i,L(function(n){if(n)r(n);else{if(i=u(),null===i)return r(null);o?$t(e):e()}})),void(o=!1))}r=a(r||l),n=n||[];var u=E(n),i=u();e()}function T(n){return o(function(t){var e,u=t.pop();try{e=n.apply(this,t)}catch(i){return u(i)}r(e)&&"function"==typeof e.then?e.then(function(n){u(null,n)})["catch"](function(n){u(n.message?n:new Error(n))}):u(null,e)})}function I(n,t){for(var r=-1,e=n.length;++r<e&&t(n[r],r,n)!==!1;);return n}function z(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return!1;return!0}function $(n){return function(t,r,e){for(var u=-1,i=Object(t),o=e(t),c=o.length;c--;){var f=o[n?c:++u];if(r(i[f],f,i)===!1)break}return t}}function M(n,t){return n&&Bt(n,t,O)}function q(n){return n}function B(n){return"function"==typeof n?n:q}function F(n,t){return n&&M(n,B(t))}function P(n,t,r){for(var e=n.length,u=t+(r?0:-1);r?u--:++u<e;){var i=n[u];if(i!==i)return u}return-1}function U(n,t,r){if(t!==t)return P(n,r);for(var e=r-1,u=n.length;++e<u;)if(n[e]===t)return e;return-1}function C(n,t,r){var e=n?n.length:0;return e?(r=i(r),0>r&&(r=Ft(e+r,0)),U(n,t,r)):-1}function D(n,t,r){function e(n){v.unshift(n)}function u(n){var t=C(v,n);t>=0&&v.splice(t,1)}function i(){f--,I(v.slice(),function(n){n()})}"function"==typeof arguments[1]&&(r=t,t=null),r=a(r||l);var c=O(n),f=c.length;if(!f)return r(null);t||(t=f);var s={},p=0,y=!1,v=[];e(function(){f||r(null,s)}),I(c,function(c){function f(){return t>p&&!h(s,c)&&z(d,function(n){return h(s,n)})}function a(){f()&&(p++,u(a),v[v.length-1](m,s))}if(!y){for(var l,v=St(n[c])?n[c]:[n[c]],m=o(function(n,t){if(p--,t.length<=1&&(t=t[0]),n){var e={};F(s,function(n,t){e[t]=n}),e[c]=t,y=!0,r(n,e)}else s[c]=t,$t(i)}),d=v.slice(0,v.length-1),g=d.length;g--;){if(!(l=n[d[g]]))throw new Error("Has non-existent dependency in "+d.join(", "));if(St(l)&&C(l,c)>=0)throw new Error("Has cyclic dependencies")}f()?(p++,v[v.length-1](m,s)):e(a)}})}function H(n,t){for(var r=-1,e=n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function N(n,t,r){function e(n,t,r,e){if(null!=e&&"function"!=typeof e)throw new Error("task callback must be a function");return n.started=!0,St(t)||(t=[t]),0===t.length&&n.idle()?$t(function(){n.drain()}):(I(t,function(t){var u={data:t,callback:e||l};r?n.tasks.unshift(u):n.tasks.push(u),n.tasks.length===n.concurrency&&n.saturated()}),void $t(n.process))}function u(n,t){return function(){i-=1;var r=!1,e=arguments;I(t,function(n){I(o,function(t,e){t!==n||r||(o.splice(e,1),r=!0)}),n.callback.apply(n,e)}),n.tasks.length+i===0&&n.drain(),n.process()}}if(null==t)t=1;else if(0===t)throw new Error("Concurrency must not be zero");var i=0,o=[],c={tasks:[],concurrency:t,payload:r,saturated:l,empty:l,drain:l,started:!1,paused:!1,push:function(n,t){e(c,n,!1,t)},kill:function(){c.drain=l,c.tasks=[]},unshift:function(n,t){e(c,n,!0,t)},process:function(){for(;!c.paused&&i<c.concurrency&&c.tasks.length;){var t=c.payload?c.tasks.splice(0,c.payload):c.tasks.splice(0,c.tasks.length),r=H(t,s("data"));0===c.tasks.length&&c.empty(),i+=1,o.push(t[0]);var e=L(u(c,t));n(r,e)}},length:function(){return c.tasks.length},running:function(){return i},workersList:function(){return o},idle:function(){return c.tasks.length+i===0},pause:function(){c.paused=!0},resume:function(){if(c.paused!==!1){c.paused=!1;for(var n=Math.min(c.concurrency,c.tasks.length),t=1;n>=t;t++)$t(c.process)}}};return c}function Q(n,t){return N(n,1,t)}function R(n,t,r,e){A(n,function(n,e,u){r(t,n,function(n,r){t=r,u(n)})},function(n){e(n,t)})}function W(){var n=arguments;return o(function(t){var r=this,e=t[t.length-1];"function"==typeof e?t.pop():e=l,R(n,t,function(n,t,e){t.apply(r,n.concat([o(function(n,t){e(n,t)})]))},function(n,t){e.apply(r,[n].concat(t))})})}function G(){return W.apply(null,Pt.call(arguments))}function J(n,t,r,e){var u=[];n(t,function(n,t,e){r(n,function(n,t){u=u.concat(t||[]),e(n)})},function(n){e(n,u)})}function K(n){return function(t,r,e){return n(x,t,r,e)}}function V(n){return function(t,r,e){return n(A,t,r,e)}}function X(n,t,r){return function(e,u,i,o){function c(n){o&&(n?o(n):o(null,r(!1,void 0)))}function f(n,e,u){return o?void i(n,function(e,c){o&&(e?(o(e),o=i=!1):t(c)&&(o(null,r(!0,n)),o=i=!1)),u()}):u()}arguments.length>3?n(e,u,f,c):(o=i,i=u,n(e,f,c))}}function Y(n,t){return t}function Z(n){return function(t,r,e){e=a(e||l),t=t||[];var u=E(t);if(0>=n)return e(null);var i=!1,o=0,c=!1;!function f(){if(i&&0>=o)return e(null);for(;n>o&&!c;){var a=u();if(null===a)return i=!0,void(0>=o&&e(null));o+=1,r(t[a],a,L(function(n){o-=1,n?(e(n),c=!0):f()}))}}()}}function _(n,t,r,e){Z(t)(n,r,e)}function nn(n){return o(function(t,r){t.apply(null,r.concat([o(function(t,r){"object"==typeof console&&(t?console.error&&console.error(t):console[n]&&I(r,function(t){console[n](t)}))})]))})}function tn(n,t,r){r=r||l;var e=o(function(t,e){t?r(t):(e.push(u),n.apply(this,e))}),u=function(n,u){return n?r(n):u?void t(e):r(null)};n(u)}function rn(n,t,r){var e=0;tn(function(n){return e++<1?n(null,!0):void t.apply(this,arguments)},n,r)}function en(n,t,r){if(r=r||l,!n())return r(null);var e=o(function(u,i){return u?r(u):n.apply(this,i)?t(e):void r.apply(null,[null].concat(i))});t(e)}function un(n,t,r){var e=0;return en(function(){return++e<=1||t.apply(this,arguments)},n,r)}function on(n,t,r){return un(n,function(){return!t.apply(this,arguments)},r)}function cn(n){return function(t,r,e){return n(t,e)}}function fn(n,t,r){return x(n,cn(t),r)}function an(n,t,r,e){return Z(t)(n,cn(r),e)}function ln(n,t,r){return A(n,cn(t),r)}function sn(n){return o(function(t){var r=t.pop(),e=!0;t.push(function(){var n=arguments;e?$t(function(){r.apply(null,n)}):r.apply(null,n)}),n.apply(this,t),e=!1})}function pn(n){return!n}function yn(n,t,r,e){var u=[];n(t,function(n,t,e){r(n,function(r,i){r?e(r):(i&&u.push({index:t,value:n}),e())})},function(n){n?e(n):e(null,H(u.sort(function(n,t){return n.index-t.index}),s("value")))})}function hn(n){return function(t,r,e,u){return n(Z(r),t,e,u)}}function vn(n,t){function r(n){return n?e(n):void u(r)}var e=L(t||l),u=sn(n);r()}function mn(n){function t(r){function e(){return n.length&&n[r].apply(null,arguments),e.next()}return e.next=function(){return r<n.length-1?t(r+1):null},e}return t(0)}function dn(n,t,r,e){e=a(e||l),t=t||[];var u=y(t)?[]:{};n(t,function(n,t,e){r(n,function(n,r){u[t]=r,e(n)})},function(n){e(n,u)})}function gn(n){return n&&n.Object===Object?n:null}function bn(n){return"symbol"==typeof n||d(n)&&sr.call(n)==ar}function kn(n){if("string"==typeof n)return n;if(null==n)return"";if(bn(n))return fr?hr.call(n):"";var t=n+"";return"0"==t&&1/n==-pr?"-0":t}function wn(n){var t=[];return kn(n).replace(vr,function(n,r,e,u){t.push(e?u.replace(mr,"$1"):r||n)}),t}function jn(n){return St(n)?n:wn(n)}function Sn(n,t){return"number"==typeof n?!0:!St(n)&&(gr.test(n)||!dr.test(n)||null!=t&&n in Object(t))}function On(n){var t=n?n.length:0;return t?n[t-1]:void 0}function En(n,t,r){var e=-1,u=n.length;0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0;for(var i=Array(u);++e<u;)i[e]=n[e+t];return i}function Ln(n,t){t=Sn(t,n)?[t+""]:jn(t);for(var r=0,e=t.length;null!=n&&e>r;)n=n[t[r++]];return r&&r==e?n:void 0}function xn(n,t,r){var e=null==n?void 0:Ln(n,t);return void 0===e?r:e}function An(n,t){return 1==t.length?n:xn(n,En(t,0,-1))}function Tn(n,t,r){if(null==n)return!1;var e=r(n,t);e||Sn(t)||(t=jn(t),n=An(n,t),null!=n&&(t=On(t),e=r(n,t)));var u=n?n.length:void 0;return e||!!u&&p(u)&&j(t,u)&&(St(n)||k(n)||b(n))}function In(n,t){return Tn(n,t,h)}function zn(n,t){var r=Object.create(null),e=Object.create(null);t=t||q;var u=o(function(u){var i=u.pop(),c=t.apply(null,u);In(r,c)?$t(function(){i.apply(null,r[c])}):In(e,c)?e[c].push(i):(e[c]=[i],n.apply(null,u.concat([o(function(n){r[c]=n;var t=e[c];delete e[c];for(var u=0,i=t.length;i>u;u++)t[u].apply(null,n)})])))});return u.memo=r,u.unmemoized=n,u}function $n(n,t,r){r=r||l;var e=y(t)?[]:{};n(t,function(n,t,r){n(o(function(n,u){u.length<=1&&(u=u[0]),e[t]=u,r(n)}))},function(n){r(n,e)})}function Mn(n,t){return $n(x,n,t)}function qn(n,t,r){return $n(Z(t),n,r)}function Bn(n,t){return N(function(t,r){n(t[0],r)},t,1)}function Fn(n,t){function r(n,t){return n.priority-t.priority}function e(n,t,r){for(var e=-1,u=n.length-1;u>e;){var i=e+(u-e+1>>>1);r(t,n[i])>=0?e=i:u=i-1}return e}function u(n,t,u,i){if(null!=i&&"function"!=typeof i)throw new Error("task callback must be a function");return n.started=!0,St(t)||(t=[t]),0===t.length?$t(function(){n.drain()}):void I(t,function(t){var o={data:t,priority:u,callback:"function"==typeof i?i:l};n.tasks.splice(e(n.tasks,o,r)+1,0,o),n.tasks.length===n.concurrency&&n.saturated(),$t(n.process)})}var i=Bn(n,t);return i.push=function(n,t,r){u(i,n,t,r)},delete i.unshift,i}function Pn(n,t,r,e){var u=kr.call(n).reverse();R(u,t,r,e)}function Un(n,t,r,e){yn(n,t,function(n,t){r(n,function(n,r){n?t(n):t(null,!r)})},e)}function Cn(n,t){return $n(A,n,t)}function Dn(n,t,r){function e(n,t){if("number"==typeof t)n.times=parseInt(t,10)||i;else{if("object"!=typeof t)throw new Error("Unsupported argument type for 'times': "+typeof t);n.times=parseInt(t.times,10)||i,n.interval=parseInt(t.interval,10)||o}}function u(n,t){function r(n,r){return function(e){n(function(n,t){e(!n||r,{err:n,result:t})},t)}}function e(n){return function(t){setTimeout(function(){t(null)},n)}}for(;f.times;){var u=!(f.times-=1);c.push(r(f.task,u)),!u&&f.interval>0&&c.push(e(f.interval))}Cn(c,function(t,r){r=r[r.length-1],(n||f.callback)(r.err,r.result)})}var i=5,o=0,c=[],f={times:i,interval:o},a=arguments.length;if(1>a||a>3)throw new Error("Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)");return 2>=a&&"function"==typeof n&&(r=t,t=n),"function"!=typeof n&&e(f,n),f.callback=r,f.task=t,f.callback?u():u}function Hn(n,t,r){function e(n,t){var r=n.criteria,e=t.criteria;return e>r?-1:r>e?1:0}Yt(n,function(n,r){t(n,function(t,e){return t?r(t):void r(null,{value:n,criteria:e})})},function(n,t){return n?r(n):void r(null,H(t.sort(e),s("value")))})}function Nn(n,t,r,e){for(var u=-1,i=xr(Lr((t-n)/(r||1)),0),o=Array(i);i--;)o[e?i:++u]=n,n+=r;return o}function Qn(n,t,r){Yt(Nn(0,n,1),t,r)}function Rn(n,t,r,e){return Zt(Nn(0,n,1),t,r,e)}function Wn(n,t,r){_t(Nn(0,n,1),t,r)}function Gn(n,t,r,e){3===arguments.length&&(e=r,r=t,t=St(n)?[]:{}),x(n,function(n,e,u){r(t,n,e,u)},function(n){e(n,t)})}function Jn(n){return function(){return(n.unmemoized||n).apply(null,arguments)}}function Kn(n,t,r){return en(function(){return!n.apply(this,arguments)},t,r)}function Vn(n,t){function r(n){return o(function(e,u){if(e)t.apply(null,[e].concat(u));else{var i=n.next();i?u.push(r(i)):u.push(t),sn(n).apply(null,u)}})}return t=a(t||l),St(n)?n.length?void r(mn(n))():t():t(new Error("First argument to waterfall must be an array of functions"))}var Xn,Yn="[object Function]",Zn="[object GeneratorFunction]",_n=Object.prototype,nt=_n.toString,tt=NaN,rt=/^\s+|\s+$/g,et=/^[-+]0x[0-9a-f]+$/i,ut=/^0b[01]+$/i,it=/^0o[0-7]+$/i,ot=parseInt,ct=1/0,ft=1.7976931348623157e308,at="Expected a function",lt=Math.max,st="Expected a function",pt=s("length"),yt=9007199254740991,ht=Object.prototype,vt=ht.hasOwnProperty,mt=Object.getPrototypeOf,dt=Object.keys,gt="[object Arguments]",bt=Object.prototype,kt=bt.hasOwnProperty,wt=bt.toString,jt=bt.propertyIsEnumerable,St=Array.isArray,Ot="[object String]",Et=Object.prototype,Lt=Et.toString,xt=9007199254740991,At=/^(?:0|[1-9]\d*)$/,Tt=Object.prototype,It=c(x),zt="function"==typeof setImmediate&&setImmediate;Xn=zt?function(n){zt(n)}:"object"==typeof process&&"function"==typeof process.nextTick?process.nextTick:function(n){setTimeout(n,0)};var $t=Xn,Mt=c(A),qt=o(function(n,t){return o(function(r){return n.apply(null,t.concat(r))})}),Bt=$(),Ft=Math.max,Pt=Array.prototype.reverse,Ut=K(J),Ct=V(J),Dt=o(function(n){var t=[null].concat(n);return function(n){return n.apply(this,t)}}),Ht=X(x,q,Y),Nt=X(_,q,Y),Qt=X(A,q,Y),Rt=nn("dir"),Wt=X(x,pn,pn),Gt=X(_,pn,pn),Jt=K(yn),Kt=hn(yn),Vt=V(yn),Xt=nn("log"),Yt=K(dn),Zt=hn(dn),_t=V(dn),nr={"function":!0,object:!0},tr=nr[typeof n]&&n&&!n.nodeType?n:null,rr=nr[typeof module]&&module&&!module.nodeType?module:null,er=gn(tr&&rr&&"object"==typeof global&&global),ur=gn(nr[typeof self]&&self),ir=gn(nr[typeof window]&&window),or=gn(nr[typeof this]&&this),cr=er||ir!==(or&&or.window)&&ir||ur||or||Function("return this")(),fr=cr.Symbol,ar="[object Symbol]",lr=Object.prototype,sr=lr.toString,pr=1/0,yr=fr?fr.prototype:void 0,hr=fr?yr.toString:void 0,vr=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,mr=/\\(\\)?/g,dr=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,gr=/^\w*$/,br="object"==typeof process&&"function"==typeof process.nextTick?process.nextTick:$t,kr=Array.prototype.slice,wr=K(Un),jr=hn(Un),Sr=V(Un),Or=X(x,Boolean,q),Er=X(_,Boolean,q),Lr=Math.ceil,xr=Math.max,Ar={applyEach:It,applyEachSeries:Mt,apply:qt,asyncify:T,auto:D,cargo:Q,compose:G,concat:Ut,concatSeries:Ct,constant:Dt,detect:Ht,detectLimit:Nt,detectSeries:Qt,dir:Rt,doDuring:rn,doUntil:on,doWhilst:un,during:tn,each:fn,eachLimit:an,eachOf:x,eachOfLimit:_,eachOfSeries:A,eachSeries:ln,ensureAsync:sn,every:Wt,everyLimit:Gt,filter:Jt,filterLimit:Kt,filterSeries:Vt,forever:vn,iterator:mn,log:Xt,map:Yt,mapLimit:Zt,mapSeries:_t,memoize:zn,nextTick:br,parallel:Mn,parallelLimit:qn,priorityQueue:Fn,queue:Bn,reduce:R,reduceRight:Pn,reject:wr,rejectLimit:jr,rejectSeries:Sr,retry:Dn,seq:W,series:Cn,setImmediate:$t,some:Or,someLimit:Er,sortBy:Hn,times:Qn,timesLimit:Rn,timesSeries:Wn,transform:Gn,unmemoize:Jn,until:Kn,waterfall:Vn,whilst:en,all:Wt,any:Or,forEach:fn,forEachSeries:ln,forEachLimit:an,forEachOf:x,forEachOfSeries:A,forEachOfLimit:_,inject:R,foldl:R,foldr:Pn,select:Jt,selectLimit:Kt,selectSeries:Vt,wrapSync:T};n["default"]=Ar,n.applyEach=It,n.applyEachSeries=Mt,n.apply=qt,n.asyncify=T,n.auto=D,n.cargo=Q,n.compose=G,n.concat=Ut,n.concatSeries=Ct,n.constant=Dt,n.detect=Ht,n.detectLimit=Nt,n.detectSeries=Qt,n.dir=Rt,n.doDuring=rn,n.doUntil=on,n.doWhilst=un,n.during=tn,n.each=fn,n.eachLimit=an,n.eachOf=x,n.eachOfLimit=_,n.eachOfSeries=A,n.eachSeries=ln,n.ensureAsync=sn,n.every=Wt,n.everyLimit=Gt,n.filter=Jt,n.filterLimit=Kt,n.filterSeries=Vt,n.forever=vn,n.iterator=mn,n.log=Xt,n.map=Yt,n.mapLimit=Zt,n.mapSeries=_t,n.memoize=zn,n.nextTick=br,n.parallel=Mn,n.parallelLimit=qn,n.priorityQueue=Fn,n.queue=Bn,n.reduce=R,n.reduceRight=Pn,n.reject=wr,n.rejectLimit=jr,n.rejectSeries=Sr,n.retry=Dn,n.seq=W,n.series=Cn,n.setImmediate=$t,n.some=Or,n.someLimit=Er,n.sortBy=Hn,n.times=Qn,n.timesLimit=Rn,n.timesSeries=Wn,n.transform=Gn,n.unmemoize=Jn,n.until=Kn,n.waterfall=Vn,n.whilst=en,n.all=Wt,n.any=Or,n.forEach=fn,n.forEachSeries=ln,n.forEachLimit=an,n.forEachOf=x,n.forEachOfSeries=A,n.forEachOfLimit=_,n.inject=R,n.foldl=R,n.foldr=Pn,n.select=Jt,n.selectLimit=Kt,n.selectSeries=Vt,n.wrapSync=T});
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.async=t.async||{})}(this,function(t){"use strict";function n(t,n,r){var e=r.length;switch(e){case 0:return t.call(n);case 1:return t.call(n,r[0]);case 2:return t.call(n,r[0],r[1]);case 3:return t.call(n,r[0],r[1],r[2])}return t.apply(n,r)}function r(t){var n=typeof t;return!!t&&("object"==n||"function"==n)}function e(t){var n=r(t)?Zn.call(t):"";return n==Vn||n==Xn}function o(t){if(r(t)){var n=e(t.valueOf)?t.valueOf():t;t=r(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(nr,"");var o=er.test(t);return o||or.test(t)?ur(t.slice(2),o?2:8):rr.test(t)?tr:+t}function u(t){if(!t)return 0===t?t:0;if(t=o(t),t===ir||t===-ir){var n=0>t?-1:1;return n*cr}var r=t%1;return t===t?r?t-r:t:0}function i(t,r){if("function"!=typeof t)throw new TypeError(ar);return r=fr(void 0===r?t.length-1:u(r),0),function(){for(var e=arguments,o=-1,u=fr(e.length-r,0),i=Array(u);++o<u;)i[o]=e[r+o];switch(r){case 0:return t.call(this,i);case 1:return t.call(this,e[0],i);case 2:return t.call(this,e[0],e[1],i)}var c=Array(r+1);for(o=-1;++o<r;)c[o]=e[o];return c[r]=i,n(t,this,c)}}function c(t){return i(function(n){var r=n.pop();t(n,r)})}function a(t){return i(function(n,r){var e=c(function(r,e){var o=this;return t(n,function(t,n,e){t.apply(o,r.concat([e]))},e)});return r.length?e.apply(this,r):e})}function f(){}function l(t,n){var r;if("function"!=typeof n)throw new TypeError(lr);return t=u(t),function(){return--t>0&&(r=n.apply(this,arguments)),1>=t&&(n=void 0),r}}function s(t){return l(2,t)}function p(t){return function(n){return null==n?void 0:n[t]}}function y(t){return"number"==typeof t&&t>-1&&t%1==0&&pr>=t}function h(t){return null!=t&&y(sr(t))&&!e(t)}function v(t){return yr&&t[yr]&&t[yr]()}function d(t,n){return vr.call(t,n)||"object"==typeof t&&n in t&&null===dr(t)}function m(t){return mr(Object(t))}function g(t,n){for(var r=-1,e=Array(t);++r<t;)e[r]=n(r);return e}function b(t){return!!t&&"object"==typeof t}function j(t){return b(t)&&h(t)}function w(t){return j(t)&&jr.call(t,"callee")&&(!Or.call(t,"callee")||wr.call(t)==gr)}function O(t){return"string"==typeof t||!Sr(t)&&b(t)&&Er.call(t)==_r}function S(t){var n=t?t.length:void 0;return y(n)&&(Sr(t)||O(t)||w(t))?g(n,String):null}function _(t,n){return t="number"==typeof t||xr.test(t)?+t:-1,n=null==n?Ar:n,t>-1&&t%1==0&&n>t}function k(t){var n=t&&t.constructor,r="function"==typeof n&&n.prototype||Lr;return t===r}function E(t){var n=k(t);if(!n&&!h(t))return m(t);var r=S(t),e=!!r,o=r||[],u=o.length;for(var i in t)!d(t,i)||e&&("length"==i||_(i,u))||n&&"constructor"==i||o.push(i);return o}function A(t){var n,r=-1;if(h(t))return n=t.length,function(){return r++,n>r?{value:t[r],key:r}:null};var e=v(t);if(e)return function(){var t=e.next();return t.done?null:(r++,{value:t.value,key:r})};var o=E(t);return n=o.length,function(){r++;var e=o[r];return n>r?{value:t[e],key:e}:null}}function x(t){return function(){if(null===t)throw new Error("Callback was already called.");t.apply(this,arguments),t=null}}function L(t){return function(n,r,e){e=s(e||f),n=n||[];var o=A(n);if(0>=t)return e(null);var u=!1,i=0,c=!1;!function a(){if(u&&0>=i)return e(null);for(;t>i&&!c;){var n=o();if(null===n)return u=!0,void(0>=i&&e(null));i+=1,r(n.value,n.key,x(function(t){i-=1,t?(e(t),c=!0):a()}))}}()}}function I(t,n,r,e){L(n)(t,r,e)}function T(t,n){return function(r,e,o){return t(r,n,e,o)}}function F(t){return c(function(n,e){var o;try{o=t.apply(this,n)}catch(u){return e(u)}r(o)&&"function"==typeof o.then?o.then(function(t){e(null,t)})["catch"](function(t){e(t.message?t:new Error(t))}):e(null,o)})}function M(t,n){for(var r=-1,e=t.length;++r<e&&n(t[r],r,t)!==!1;);return t}function $(t){return t}function U(t){return"function"==typeof t?t:$}function P(t){return function(n,r,e){for(var o=-1,u=Object(n),i=e(n),c=i.length;c--;){var a=i[t?c:++o];if(r(u[a],a,u)===!1)break}return n}}function z(t,n){return t&&Ur(t,n,E)}function B(t,n){return t&&z(t,U(n))}function C(t,n,r){for(var e=t.length,o=n+(r?0:-1);r?o--:++o<e;){var u=t[o];if(u!==u)return o}return-1}function q(t,n,r){if(n!==n)return C(t,r);for(var e=r-1,o=t.length;++e<o;)if(t[e]===n)return e;return-1}function D(t,n,r){var e=t?t.length:0;return e?(r=u(r),0>r&&(r=Pr(e+r,0)),q(t,n,r)):-1}function R(t,n,r){function e(t,n){m.push(function(){a(t,n)})}function o(){if(0===m.length&&0===h)return r(null,y);for(;m.length&&n>h;){var t=m.shift();t()}}function u(t,n){var r=d[t];r||(r=d[t]=[]),r.push(n)}function c(t){var n=d[t]||[];M(n,function(t){t()}),o()}function a(t,n){if(!v){var e=x(i(function(n,e){if(h--,e.length<=1&&(e=e[0]),n){var o={};B(y,function(t,n){o[n]=t}),o[t]=e,v=!0,d=[],r(n,o)}else y[t]=e,c(t)}));h++;var o=n[n.length-1];n.length>1?o(y,e):o(e)}}"function"==typeof n&&(r=n,n=null),r=s(r||f);var l=E(t),p=l.length;if(!p)return r(null);n||(n=p);var y={},h=0,v=!1,d={},m=[];B(t,function(n,r){function o(){for(var n,e=i.length;e--;){if(!(n=t[i[e]]))throw new Error("async.auto task `"+r+"` has non-existent dependency in "+i.join(", "));if(Sr(n)&&D(n,r)>=0)throw new Error("async.auto task `"+r+"`Has cyclic dependencies")}}if(!Sr(n))return void e(r,[n]);var i=n.slice(0,n.length-1),c=i.length;o(),M(i,function(t){u(t,function(){c--,0===c&&e(r,n)})})}),o()}function W(t,n){for(var r=-1,e=t.length,o=Array(e);++r<e;)o[r]=n(t[r],r,t);return o}function N(){this.__data__={array:[],map:null}}function G(t,n){return t===n||t!==t&&n!==n}function Q(t,n){for(var r=t.length;r--;)if(G(t[r][0],n))return r;return-1}function H(t,n){var r=Q(t,n);if(0>r)return!1;var e=t.length-1;return r==e?t.pop():Br.call(t,r,1),!0}function J(t){var n=this.__data__,r=n.array;return r?H(r,t):n.map["delete"](t)}function K(t,n){var r=Q(t,n);return 0>r?void 0:t[r][1]}function V(t){var n=this.__data__,r=n.array;return r?K(r,t):n.map.get(t)}function X(t,n){return Q(t,n)>-1}function Y(t){var n=this.__data__,r=n.array;return r?X(r,t):n.map.has(t)}function Z(t){var n=!1;if(null!=t&&"function"!=typeof t.toString)try{n=!!(t+"")}catch(r){}return n}function tt(t){return null==t?!1:e(t)?Nr.test(Rr.call(t)):b(t)&&(Z(t)?Nr:qr).test(t)}function nt(t,n){var r=t[n];return tt(r)?r:void 0}function rt(){}function et(t){return t&&t.Object===Object?t:null}function ot(){this.__data__={hash:new rt,map:ne?new ne:[],string:new rt}}function ut(t,n){return Gr?void 0!==t[n]:ee.call(t,n)}function it(t,n){return ut(t,n)&&delete t[n]}function ct(t){var n=typeof t;return"number"==n||"boolean"==n||"string"==n&&"__proto__"!=t||null==t}function at(t){var n=this.__data__;return ct(t)?it("string"==typeof t?n.string:n.hash,t):ne?n.map["delete"](t):H(n.map,t)}function ft(t,n){if(Gr){var r=t[n];return r===oe?void 0:r}return ie.call(t,n)?t[n]:void 0}function lt(t){var n=this.__data__;return ct(t)?ft("string"==typeof t?n.string:n.hash,t):ne?n.map.get(t):K(n.map,t)}function st(t){var n=this.__data__;return ct(t)?ut("string"==typeof t?n.string:n.hash,t):ne?n.map.has(t):X(n.map,t)}function pt(t,n,r){var e=Q(t,n);0>e?t.push([n,r]):t[e][1]=r}function yt(t,n,r){t[n]=Gr&&void 0===r?ce:r}function ht(t,n){var r=this.__data__;return ct(t)?yt("string"==typeof t?r.string:r.hash,t,n):ne?r.map.set(t,n):pt(r.map,t,n),this}function vt(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function dt(t,n){var r=this.__data__,e=r.array;e&&(e.length<ae-1?pt(e,t,n):(r.array=null,r.map=new vt(e)));var o=r.map;return o&&o.set(t,n),this}function mt(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function gt(t,n,r){var e=t[n];le.call(t,n)&&G(e,r)&&(void 0!==r||n in t)||(t[n]=r)}function bt(t,n,r,e){r||(r={});for(var o=-1,u=n.length;++o<u;){var i=n[o],c=e?e(r[i],t[i],i,r,t):t[i];gt(r,i,c)}return r}function jt(t,n,r){return bt(t,n,r)}function wt(t,n){return t&&jt(n,E(n),t)}function Ot(t,n){if(n)return t.slice();var r=new t.constructor(t.length);return t.copy(r),r}function St(t,n){var r=-1,e=t.length;for(n||(n=Array(e));++r<e;)n[r]=t[r];return n}function _t(t,n){return jt(t,pe(t),n)}function kt(t){return we.call(t)}function Et(t){var n=t.length,r=t.constructor(n);return n&&"string"==typeof t[0]&&Ae.call(t,"index")&&(r.index=t.index,r.input=t.input),r}function At(t){var n=new t.constructor(t.byteLength);return new xe(n).set(new xe(t)),n}function xt(t,n){return t.set(n[0],n[1]),t}function Lt(t,n,r,e){var o=-1,u=t.length;for(e&&u&&(r=t[++o]);++o<u;)r=n(r,t[o],o,t);return r}function It(t){var n=-1,r=Array(t.size);return t.forEach(function(t,e){r[++n]=[e,t]}),r}function Tt(t){return Lt(It(t),xt,new t.constructor)}function Ft(t){var n=new t.constructor(t.source,Le.exec(t));return n.lastIndex=t.lastIndex,n}function Mt(t,n){return t.add(n),t}function $t(t){var n=-1,r=Array(t.size);return t.forEach(function(t){r[++n]=t}),r}function Ut(t){return Lt($t(t),Mt,new t.constructor)}function Pt(t){return Fe?Object(Fe.call(t)):{}}function zt(t,n){var r=n?At(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}function Bt(t,n,r){var e=t.constructor;switch(n){case De:return At(t);case Me:case $e:return new e(+t);case Re:case We:case Ne:case Ge:case Qe:case He:case Je:case Ke:case Ve:return zt(t,r);case Ue:return Tt(t);case Pe:case Ce:return new e(t);case ze:return Ft(t);case Be:return Ut(t);case qe:return Pt(t)}}function Ct(t){return r(t)?Xe(t):{}}function qt(t){return"function"!=typeof t.constructor||k(t)?{}:Ct(Ye(t))}function Dt(t){return function(){return t}}function Rt(t,n,e,o,u,i,c){var a;if(o&&(a=i?o(t,u,i,c):o(t)),void 0!==a)return a;if(!r(t))return t;var f=Sr(t);if(f){if(a=Et(t),!n)return St(t,a)}else{var l=ke(t),s=l==lo||l==so;if(oo(t))return Ot(t,n);if(l==ho||l==uo||s&&!i){if(Z(t))return i?t:{};if(a=qt(s?{}:t),!n)return a=wt(a,t),e?_t(t,a):a}else{if(!To[l])return i?t:{};a=Bt(t,l,n)}}c||(c=new mt);var p=c.get(t);return p?p:(c.set(t,a),(f?M:z)(t,function(r,u){gt(a,u,Rt(r,n,e,o,u,t,c))}),e&&!f?_t(t,a):a)}function Wt(t){return t.toString().match(Mo)[1].split(/\s*\,\s*/)}function Nt(t,n){var r={};B(t,function(t,n){function e(n,r){var e=W(o,function(t){return n[t]});e.push(r),t.apply(null,e)}var o;if(Sr(t))o=Rt(t),t=o.pop(),r[n]=o.concat(e);else{if(0===t.length)throw new Error("autoInject task functions require explicit parameters.");1===t.length?r[n]=t:(o=Wt(t),o.pop(),r[n]=o.concat(e))}}),R(r,n)}function Gt(t,n,r){function e(t,n,r,e){if(null!=e&&"function"!=typeof e)throw new Error("task callback must be a function");return t.started=!0,Sr(n)||(n=[n]),0===n.length&&t.idle()?Uo(function(){t.drain()}):(M(n,function(n){var o={data:n,callback:e||f};r?t.tasks.unshift(o):t.tasks.push(o)}),void Uo(t.process))}function o(t,n){return function(){u-=1;var r=!1,e=arguments;M(n,function(t){M(i,function(n,e){n!==t||r||(i.splice(e,1),r=!0)}),t.callback.apply(t,e)}),u<=t.concurrency-t.buffer&&t.unsaturated(),t.tasks.length+u===0&&t.drain(),t.process()}}if(null==n)n=1;else if(0===n)throw new Error("Concurrency must not be zero");var u=0,i=[],c={tasks:[],concurrency:n,payload:r,saturated:f,unsaturated:f,buffer:n/4,empty:f,drain:f,started:!1,paused:!1,push:function(t,n){e(c,t,!1,n)},kill:function(){c.drain=f,c.tasks=[]},unshift:function(t,n){e(c,t,!0,n)},process:function(){for(;!c.paused&&u<c.concurrency&&c.tasks.length;){var n=c.payload?c.tasks.splice(0,c.payload):c.tasks.splice(0,c.tasks.length),r=W(n,p("data"));0===c.tasks.length&&c.empty(),u+=1,i.push(n[0]),u===c.concurrency&&c.saturated();var e=x(o(c,n));t(r,e)}},length:function(){return c.tasks.length},running:function(){return u},workersList:function(){return i},idle:function(){return c.tasks.length+u===0},pause:function(){c.paused=!0},resume:function(){if(c.paused!==!1){c.paused=!1;for(var t=Math.min(c.concurrency,c.tasks.length),n=1;t>=n;n++)Uo(c.process)}}};return c}function Qt(t,n){return Gt(t,1,n)}function Ht(t,n,r,e){Fr(t,function(t,e,o){r(n,t,function(t,r){n=r,o(t)})},function(t){e(t,n)})}function Jt(){var t=arguments;return i(function(n){var r=this,e=n[n.length-1];"function"==typeof e?n.pop():e=f,Ht(t,n,function(t,n,e){n.apply(r,t.concat([i(function(t,n){e(t,n)})]))},function(t,n){e.apply(r,[t].concat(n))})})}function Kt(){return Jt.apply(null,Po.call(arguments))}function Vt(t,n,r,e){var o=[];t(n,function(t,n,e){r(t,function(t,n){o=o.concat(n||[]),e(t)})},function(t){e(t,o)})}function Xt(t){return function(n,r,e){return t(Ir,n,r,e)}}function Yt(t){return function(n,r,e){return t(Fr,n,r,e)}}function Zt(t,n,r){return function(e,o,u,i){function c(t){i&&(t?i(t):i(null,r(!1)))}function a(t,e,o){return i?void u(t,function(e,c){i&&(e?(i(e),i=u=!1):n(c)&&(i(null,r(!0,t)),i=u=!1)),o()}):o()}arguments.length>3?t(e,o,a,c):(i=u,u=o,t(e,a,c))}}function tn(t,n){return n}function nn(t){return i(function(n,r){n.apply(null,r.concat([i(function(n,r){"object"==typeof console&&(n?console.error&&console.error(n):console[t]&&M(r,function(n){console[t](n)}))})]))})}function rn(t,n,r){r=r||f;var e=i(function(n,e){n?r(n):(e.push(o),t.apply(this,e))}),o=function(t,o){return t?r(t):o?void n(e):r(null)};t(o)}function en(t,n,r){var e=0;rn(function(t){return e++<1?t(null,!0):void n.apply(this,arguments)},t,r)}function on(t,n,r){if(r=r||f,!t())return r(null);var e=i(function(o,u){return o?r(o):t.apply(this,u)?n(e):void r.apply(null,[null].concat(u))});n(e)}function un(t,n,r){var e=0;return on(function(){return++e<=1||n.apply(this,arguments)},t,r)}function cn(t,n,r){return un(t,function(){return!n.apply(this,arguments)},r)}function an(t){return function(n,r,e){return t(n,e)}}function fn(t,n,r,e){return L(n)(t,an(r),e)}function ln(t){return c(function(n,r){var e=!0;n.push(function(){var t=arguments;e?Uo(function(){r.apply(null,t)}):r.apply(null,t)}),t.apply(this,n),e=!1})}function sn(t){return!t}function pn(t,n,r,e){var o=[];t(n,function(t,n,e){r(t,function(r,u){r?e(r):(u&&o.push({index:n,value:t}),e())})},function(t){t?e(t):e(null,W(o.sort(function(t,n){return t.index-n.index}),p("value")))})}function yn(t){return function(n,r,e,o){return t(L(r),n,e,o)}}function hn(t,n){function r(t){return t?e(t):void o(r)}var e=x(n||f),o=ln(t);r()}function vn(t){function n(r){function e(){return t.length&&t[r].apply(null,arguments),e.next()}return e.next=function(){return r<t.length-1?n(r+1):null},e}return n(0)}function dn(t,n,r,e){e=s(e||f),n=n||[];var o=h(n)||v(n)?[]:{};t(n,function(t,n,e){r(t,function(t,r){o[n]=r,e(t)})},function(t){e(t,o)})}function mn(t){return"symbol"==typeof t||b(t)&&ou.call(t)==ru}function gn(t){if("string"==typeof t)return t;if(null==t)return"";if(mn(t))return cu?cu.call(t):"";var n=t+"";return"0"==n&&1/t==-uu?"-0":n}function bn(t){var n=[];return gn(t).replace(au,function(t,r,e,o){n.push(e?o.replace(fu,"$1"):r||t)}),n}function jn(t){return Sr(t)?t:bn(t)}function wn(t,n){return"number"==typeof t?!0:!Sr(t)&&(su.test(t)||!lu.test(t)||null!=n&&t in Object(n))}function On(t){var n=t?t.length:0;return n?t[n-1]:void 0}function Sn(t,n,r){var e=-1,o=t.length;0>n&&(n=-n>o?0:o+n),r=r>o?o:r,0>r&&(r+=o),o=n>r?0:r-n>>>0,n>>>=0;for(var u=Array(o);++e<o;)u[e]=t[e+n];return u}function _n(t,n){n=wn(n,t)?[n+""]:jn(n);for(var r=0,e=n.length;null!=t&&e>r;)t=t[n[r++]];return r&&r==e?t:void 0}function kn(t,n,r){var e=null==t?void 0:_n(t,n);return void 0===e?r:e}function En(t,n){return 1==n.length?t:kn(t,Sn(n,0,-1))}function An(t,n,r){if(null==t)return!1;var e=r(t,n);e||wn(n)||(n=jn(n),t=En(t,n),null!=t&&(n=On(n),e=r(t,n)));var o=t?t.length:void 0;return e||!!o&&y(o)&&_(n,o)&&(Sr(t)||O(t)||w(t))}function xn(t,n){return An(t,n,d)}function Ln(t,n){var r=Object.create(null),e=Object.create(null);n=n||$;var o=c(function(o,u){var c=n.apply(null,o);xn(r,c)?Uo(function(){u.apply(null,r[c])}):xn(e,c)?e[c].push(u):(e[c]=[u],t.apply(null,o.concat([i(function(t){r[c]=t;var n=e[c];delete e[c];for(var o=0,u=n.length;u>o;o++)n[o].apply(null,t)})])))});return o.memo=r,o.unmemoized=t,o}function In(t,n,r){r=r||f;var e=h(n)?[]:{};t(n,function(t,n,r){t(i(function(t,o){o.length<=1&&(o=o[0]),e[n]=o,r(t)}))},function(t){r(t,e)})}function Tn(t,n,r){return In(L(n),t,r)}function Fn(t,n){return Gt(function(n,r){t(n[0],r)},n,1)}function Mn(t,n){function r(t,n){return t.priority-n.priority}function e(t,n,r){for(var e=-1,o=t.length-1;o>e;){var u=e+(o-e+1>>>1);r(n,t[u])>=0?e=u:o=u-1}return e}function o(t,n,o,u){if(null!=u&&"function"!=typeof u)throw new Error("task callback must be a function");return t.started=!0,Sr(n)||(n=[n]),0===n.length?Uo(function(){t.drain()}):void M(n,function(n){var i={data:n,priority:o,callback:"function"==typeof u?u:f};t.tasks.splice(e(t.tasks,i,r)+1,0,i),t.tasks.length===t.concurrency&&t.saturated(),t.tasks.length<=t.concurrency-t.buffer&&t.unsaturated(),Uo(t.process)})}var u=Fn(t,n);return u.push=function(t,n,r){o(u,t,n,r)},delete u.unshift,u}function $n(t,n){return function(r,e){if(null==r)return r;if(!h(r))return t(r,e);for(var o=r.length,u=n?o:-1,i=Object(r);(n?u--:++u<o)&&e(i[u],u,i)!==!1;);return r}}function Un(t,n){return"function"==typeof n&&Sr(t)?M(t,n):yu(t,U(n))}function Pn(t,n){return n=s(n||f),Sr(t)?t.length?void Un(t,function(t){t(n)}):n():n(new TypeError("First argument to race must be an array of functions"))}function zn(t,n,r,e){var o=hu.call(t).reverse();Ht(o,n,r,e)}function Bn(t,n,r,e){pn(t,n,function(t,n){r(t,function(t,r){t?n(t):n(null,!r)})},e)}function Cn(t,n){return In(Fr,t,n)}function qn(t,n,r){function e(t,n){if("object"==typeof n)t.times=+n.times||i,t.interval=+n.interval||c;else{if("number"!=typeof n&&"string"!=typeof n)throw new Error("Invalid arguments for async.retry");t.times=+n||i}}function o(t){return function(r){n(function(n,e){r(!n||t,{err:n,result:e})})}}function u(t){return function(n){setTimeout(function(){n(null)},t)}}var i=5,c=0,a={times:i,interval:c};if(arguments.length<3&&"function"==typeof t?(r=n||f,n=t):(e(a,t),r=r||f),"function"!=typeof n)throw new Error("Invalid arguments for async.retry");for(var l=[];a.times;){var s=!(a.times-=1);l.push(o(s)),!s&&a.interval>0&&l.push(u(a.interval))}Cn(l,function(t,n){n=n[n.length-1],r(n.err,n.result)})}function Dn(t,n){return n||(n=t,t=null),c(function(r,e){function o(t){n.apply(null,r.concat([t]))}t?qn(t,o,e):qn(o,e)})}function Rn(t,n,r){function e(t,n){var r=t.criteria,e=n.criteria;return e>r?-1:r>e?1:0}tu(t,function(t,r){n(t,function(n,e){return n?r(n):void r(null,{value:t,criteria:e})})},function(t,n){return t?r(t):void r(null,W(n.sort(e),p("value")))})}function Wn(t,n){function r(){i||(o.apply(null,arguments),clearTimeout(u))}function e(){var t=new Error("Callback function timed out.");t.code="ETIMEDOUT",i=!0,o(t)}var o,u,i=!1;return c(function(i,c){o=c,u=setTimeout(e,n),t.apply(null,i.concat(r))})}function Nn(t,n,r,e){for(var o=-1,u=Ou(wu((n-t)/(r||1)),0),i=Array(u);u--;)i[e?u:++o]=t,t+=r;return i}function Gn(t,n,r,e){return Zo(Nn(0,t,1),n,r,e)}function Qn(t,n,r,e){3===arguments.length&&(e=r,r=n,n=Sr(t)?[]:{}),Ir(t,function(t,e,o){r(n,t,e,o)},function(t){e(t,n)})}function Hn(t){return function(){return(t.unmemoized||t).apply(null,arguments)}}function Jn(t,n,r){return on(function(){return!t.apply(this,arguments)},n,r)}function Kn(t,n){function r(o){if(e===t.length)return n.apply(null,[null].concat(o));var u=x(i(function(t,e){return t?n.apply(null,[t].concat(e)):void r(e)}));o.push(u);var c=t[e++];c.apply(null,o)}if(n=s(n||f),!Sr(t))return n(new Error("First argument to waterfall must be an array of functions"));if(!t.length)return n();var e=0;r([])}var Vn="[object Function]",Xn="[object GeneratorFunction]",Yn=Object.prototype,Zn=Yn.toString,tr=NaN,nr=/^\s+|\s+$/g,rr=/^[-+]0x[0-9a-f]+$/i,er=/^0b[01]+$/i,or=/^0o[0-7]+$/i,ur=parseInt,ir=1/0,cr=1.7976931348623157e308,ar="Expected a function",fr=Math.max,lr="Expected a function",sr=p("length"),pr=9007199254740991,yr="function"==typeof Symbol&&Symbol.iterator,hr=Object.prototype,vr=hr.hasOwnProperty,dr=Object.getPrototypeOf,mr=Object.keys,gr="[object Arguments]",br=Object.prototype,jr=br.hasOwnProperty,wr=br.toString,Or=br.propertyIsEnumerable,Sr=Array.isArray,_r="[object String]",kr=Object.prototype,Er=kr.toString,Ar=9007199254740991,xr=/^(?:0|[1-9]\d*)$/,Lr=Object.prototype,Ir=T(I,1/0),Tr=a(Ir),Fr=T(I,1),Mr=a(Fr),$r=i(function(t,n){return i(function(r){return t.apply(null,n.concat(r))})}),Ur=P(),Pr=Math.max,zr=Array.prototype,Br=zr.splice,Cr=/[\\^$.*+?()[\]{}|]/g,qr=/^\[object .+?Constructor\]$/,Dr=Object.prototype,Rr=Function.prototype.toString,Wr=Dr.hasOwnProperty,Nr=RegExp("^"+Rr.call(Wr).replace(Cr,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Gr=nt(Object,"create"),Qr=Object.prototype;rt.prototype=Gr?Gr(null):Qr;var Hr={"function":!0,object:!0},Jr=Hr[typeof t]&&t&&!t.nodeType?t:void 0,Kr=Hr[typeof module]&&module&&!module.nodeType?module:void 0,Vr=et(Jr&&Kr&&"object"==typeof global&&global),Xr=et(Hr[typeof self]&&self),Yr=et(Hr[typeof window]&&window),Zr=et(Hr[typeof this]&&this),te=Vr||Yr!==(Zr&&Zr.window)&&Yr||Xr||Zr||Function("return this")(),ne=nt(te,"Map"),re=Object.prototype,ee=re.hasOwnProperty,oe="__lodash_hash_undefined__",ue=Object.prototype,ie=ue.hasOwnProperty,ce="__lodash_hash_undefined__";vt.prototype.clear=ot,vt.prototype["delete"]=at,vt.prototype.get=lt,vt.prototype.has=st,vt.prototype.set=ht;var ae=200;mt.prototype.clear=N,mt.prototype["delete"]=J,mt.prototype.get=V,mt.prototype.has=Y,mt.prototype.set=dt;var fe=Object.prototype,le=fe.hasOwnProperty,se=Object.getOwnPropertySymbols,pe=se||function(){return[]},ye=nt(te,"Set"),he=nt(te,"WeakMap"),ve="[object Map]",de="[object Object]",me="[object Set]",ge="[object WeakMap]",be=Object.prototype,je=Function.prototype.toString,we=be.toString,Oe=ne?je.call(ne):"",Se=ye?je.call(ye):"",_e=he?je.call(he):"";(ne&&kt(new ne)!=ve||ye&&kt(new ye)!=me||he&&kt(new he)!=ge)&&(kt=function(t){var n=we.call(t),r=n==de?t.constructor:null,e="function"==typeof r?je.call(r):"";if(e)switch(e){case Oe:return ve;case Se:return me;case _e:return ge}return n});var ke=kt,Ee=Object.prototype,Ae=Ee.hasOwnProperty,xe=te.Uint8Array,Le=/\w*$/,Ie=te.Symbol,Te=Ie?Ie.prototype:void 0,Fe=Te?Te.valueOf:void 0,Me="[object Boolean]",$e="[object Date]",Ue="[object Map]",Pe="[object Number]",ze="[object RegExp]",Be="[object Set]",Ce="[object String]",qe="[object Symbol]",De="[object ArrayBuffer]",Re="[object Float32Array]",We="[object Float64Array]",Ne="[object Int8Array]",Ge="[object Int16Array]",Qe="[object Int32Array]",He="[object Uint8Array]",Je="[object Uint8ClampedArray]",Ke="[object Uint16Array]",Ve="[object Uint32Array]",Xe=Object.create,Ye=Object.getPrototypeOf,Ze={"function":!0,object:!0},to=Ze[typeof t]&&t&&!t.nodeType?t:void 0,no=Ze[typeof module]&&module&&!module.nodeType?module:void 0,ro=no&&no.exports===to?to:void 0,eo=ro?te.Buffer:void 0,oo=eo?function(t){return t instanceof eo}:Dt(!1),uo="[object Arguments]",io="[object Array]",co="[object Boolean]",ao="[object Date]",fo="[object Error]",lo="[object Function]",so="[object GeneratorFunction]",po="[object Map]",yo="[object Number]",ho="[object Object]",vo="[object RegExp]",mo="[object Set]",go="[object String]",bo="[object Symbol]",jo="[object WeakMap]",wo="[object ArrayBuffer]",Oo="[object Float32Array]",So="[object Float64Array]",_o="[object Int8Array]",ko="[object Int16Array]",Eo="[object Int32Array]",Ao="[object Uint8Array]",xo="[object Uint8ClampedArray]",Lo="[object Uint16Array]",Io="[object Uint32Array]",To={};To[uo]=To[io]=To[wo]=To[co]=To[ao]=To[Oo]=To[So]=To[_o]=To[ko]=To[Eo]=To[po]=To[yo]=To[ho]=To[vo]=To[mo]=To[go]=To[bo]=To[Ao]=To[xo]=To[Lo]=To[Io]=!0,To[fo]=To[lo]=To[jo]=!1;var Fo,Mo=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,$o="function"==typeof setImmediate&&setImmediate;Fo=$o?$o:"object"==typeof process&&"function"==typeof process.nextTick?process.nextTick:function(t){setTimeout(t,0)};var Uo=i(function(t,n){Fo(function(){t.apply(null,n)})}),Po=Array.prototype.reverse,zo=Xt(Vt),Bo=Yt(Vt),Co=i(function(t){var n=[null].concat(t);return c(function(t,r){return r.apply(this,n)})}),qo=Zt(Ir,$,tn),Do=Zt(I,$,tn),Ro=Zt(Fr,$,tn),Wo=nn("dir"),No=T(fn,1/0),Go=T(fn,1),Qo=Zt(I,sn,sn),Ho=T(Qo,1/0),Jo=T(Qo,1),Ko=yn(pn),Vo=T(Ko,1/0),Xo=T(Ko,1),Yo=nn("log"),Zo=yn(dn),tu=T(Zo,1/0),nu=T(Zo,1),ru="[object Symbol]",eu=Object.prototype,ou=eu.toString,uu=1/0,iu=Ie?Ie.prototype:void 0,cu=iu?iu.toString:void 0,au=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,fu=/\\(\\)?/g,lu=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,su=/^\w*$/,pu=T(Tn,1/0),yu=$n(z),hu=Array.prototype.slice,vu=yn(Bn),du=T(vu,1/0),mu=T(vu,1),gu=Zt(I,Boolean,$),bu=T(gu,1/0),ju=T(gu,1),wu=Math.ceil,Ou=Math.max,Su=T(Gn,1/0),_u=T(Gn,1),ku={applyEach:Tr,applyEachSeries:Mr,apply:$r,asyncify:F,auto:R,autoInject:Nt,cargo:Qt,compose:Kt,concat:zo,concatSeries:Bo,constant:Co,detect:qo,detectLimit:Do,detectSeries:Ro,dir:Wo,doDuring:en,doUntil:cn,doWhilst:un,during:rn,each:No,eachLimit:fn,eachOf:Ir,eachOfLimit:I,eachOfSeries:Fr,eachSeries:Go,ensureAsync:ln,every:Ho,everyLimit:Qo,everySeries:Jo,filter:Vo,filterLimit:Ko,filterSeries:Xo,forever:hn,iterator:vn,log:Yo,map:tu,mapLimit:Zo,mapSeries:nu,memoize:Ln,nextTick:Uo,parallel:pu,parallelLimit:Tn,priorityQueue:Mn,queue:Fn,race:Pn,reduce:Ht,reduceRight:zn,reject:du,rejectLimit:vu,rejectSeries:mu,retry:qn,retryable:Dn,seq:Jt,series:Cn,setImmediate:Uo,some:bu,someLimit:gu,someSeries:ju,sortBy:Rn,timeout:Wn,times:Su,timesLimit:Gn,timesSeries:_u,transform:Qn,unmemoize:Hn,until:Jn,waterfall:Kn,whilst:on,all:Ho,any:bu,forEach:No,forEachSeries:Go,forEachLimit:fn,forEachOf:Ir,forEachOfSeries:Fr,forEachOfLimit:I,inject:Ht,foldl:Ht,foldr:zn,select:Vo,selectLimit:Ko,selectSeries:Xo,wrapSync:F};t["default"]=ku,t.applyEach=Tr,t.applyEachSeries=Mr,t.apply=$r,t.asyncify=F,t.auto=R,t.autoInject=Nt,t.cargo=Qt,t.compose=Kt,t.concat=zo,t.concatSeries=Bo,t.constant=Co,t.detect=qo,t.detectLimit=Do,t.detectSeries=Ro,t.dir=Wo,t.doDuring=en,t.doUntil=cn,t.doWhilst=un,t.during=rn,t.each=No,t.eachLimit=fn,t.eachOf=Ir,t.eachOfLimit=I,t.eachOfSeries=Fr,t.eachSeries=Go,t.ensureAsync=ln,t.every=Ho,t.everyLimit=Qo,t.everySeries=Jo,t.filter=Vo,t.filterLimit=Ko,t.filterSeries=Xo,t.forever=hn,t.iterator=vn,t.log=Yo,t.map=tu,t.mapLimit=Zo,t.mapSeries=nu,t.memoize=Ln,t.nextTick=Uo,t.parallel=pu,t.parallelLimit=Tn,t.priorityQueue=Mn,t.queue=Fn,t.race=Pn,t.reduce=Ht,t.reduceRight=zn,t.reject=du,t.rejectLimit=vu,t.rejectSeries=mu,t.retry=qn,t.retryable=Dn,t.seq=Jt,t.series=Cn,t.setImmediate=Uo,t.some=bu,t.someLimit=gu,t.someSeries=ju,t.sortBy=Rn,t.timeout=Wn,t.times=Su,t.timesLimit=Gn,t.timesSeries=_u,t.transform=Qn,t.unmemoize=Hn,t.until=Jn,t.waterfall=Kn,t.whilst=on,t.all=Ho,t.allLimit=Qo,t.allSeries=Jo,t.any=bu,t.anyLimit=gu,t.anySeries=ju,t.find=qo,t.findLimit=Do,t.findSeries=Ro,t.forEach=No,t.forEachSeries=Go,t.forEachLimit=fn,t.forEachOf=Ir,t.forEachOfSeries=Fr,t.forEachOfLimit=I,t.inject=Ht,t.foldl=Ht,t.foldr=zn,t.select=Vo,t.selectLimit=Ko,t.selectSeries=Xo,t.wrapSync=F});
//# sourceMappingURL=dist/async.min.map \ No newline at end of file
diff --git a/dist/async.min.map b/dist/async.min.map
index 9156fcc..f6fc563 100644
--- a/dist/async.min.map
+++ b/dist/async.min.map
@@ -1 +1 @@
-{"version":3,"file":"build/dist/async.min.js","sources":["build/dist/async.js"],"names":["global","factory","exports","module","define","amd","async","this","apply$1","func","thisArg","args","length","call","apply","isObject","value","type","isFunction","tag","objectToString$2","funcTag","genTag","toNumber","other","valueOf","replace","reTrim","isBinary","reIsBinary","test","reIsOctal","freeParseInt","slice","reIsBadHex","NAN","toInteger","INFINITY","sign","MAX_INTEGER","remainder","rest","start","TypeError","FUNC_ERROR_TEXT","nativeMax","undefined","arguments","index","array","Array","otherArgs","applyEach$1","eachfn","fns","go","that","callback","pop","fn","_","cb","concat","before","n","result","FUNC_ERROR_TEXT$1","once","noop","baseProperty","key","object","isLength","MAX_SAFE_INTEGER$1","isArrayLike","getLength","baseHas","hasOwnProperty","getPrototypeOf","baseKeys","nativeKeys","Object","baseTimes","iteratee","isObjectLike","isArrayLikeObject","isArguments","hasOwnProperty$1","propertyIsEnumerable","objectToString","argsTag","isString","isArray","objectToString$1","stringTag","indexKeys","String","isIndex","reIsUint","MAX_SAFE_INTEGER","isPrototype","Ctor","constructor","proto","prototype","objectProto$1","keys","isProto","indexes","skipIndexes","push","keyIterator","coll","len","i","okeys","onlyOnce","Error","eachOf","iterator","done","err","completed","iter","eachOfSeries","obj","iterate","sync","nextKey","setImmediate$1","asyncify","e","then","message","arrayEach","arrayEvery","predicate","createBaseFor","fromRight","keysFunc","iterable","props","baseForOwn","baseFor","identity","toFunction","forOwn","indexOfNaN","fromIndex","baseIndexOf","indexOf","nativeMax$1","auto","tasks","concurrency","addListener","listeners","unshift","removeListener","idx","splice","taskComplete","remainingTasks","keys$$","results","runningTasks","hasError","k","ready","requires","x","listener","task","taskCallback","dep","safeResults","val","rkey","join","arrayMap","queue$1","worker","payload","_insert","q","data","pos","started","idle","drain","item","saturated","process","_next","workers","removed","workersList","empty","paused","kill","running","pause","resume","resumeCount","Math","min","w","cargo","reduce","arr","memo","v","seq","newargs","nextargs","compose","reverse","concat$1","y","doParallel","doSeries","_createTester","check","getResult","limit","_findGetResult","_eachOfLimit","errored","replenish","eachOfLimit","consoleFunc","name","console","error","during","next","truth","doDuring","calls","whilst","doWhilst","doUntil","_withoutIndex","each","eachLimit","eachSeries","ensureAsync","innerArgs","notId","_filter","sort","a","b","doParallelLimit","forever","makeCallback","_asyncMap","checkGlobal","isSymbol","objectToString$3","symbolTag","toString","Symbol","symbolToString","INFINITY$1","stringToPath","string","rePropName","match","number","quote","reEscapeChar","baseToPath","isKey","reIsPlainProp","reIsDeepProp","last","baseSlice","end","baseGet","path","get","defaultValue","parent","hasPath","hasFunc","has","memoize","hasher","create","queues","memoized","l","unmemoized","_parallel","parallel","parallelLimit","queue","items","priorityQueue","_compareTasks","priority","_binarySearch","sequence","compare","beg","mid","reduceRight","reversed","reject$1","series","retry","times","parseTimes","acc","t","parseInt","DEFAULT_TIMES","interval","DEFAULT_INTERVAL","wrappedTask","wrappedCallback","wrappedResults","retryAttempt","finalAttempt","seriesCallback","retryInterval","setTimeout","opts","attempts","sortBy","comparator","left","right","criteria","map","baseRange","step","nativeMax$2","nativeCeil","count","timeLimit","mapLimit","timesSeries","mapSeries","transform","unmemoize","until","waterfall","wrapIterator","_delay","objectProto$4","max","objectProto","objectProto$2","objectProto$3","applyEach","_setImmediate","setImmediate","nextTick","applyEachSeries","callArgs","concatSeries","constant","values","detect","detectLimit","detectSeries","dir","every","everyLimit","filter","filterLimit","filterSeries","log","objectTypes","function","freeExports","nodeType","freeModule","freeGlobal","freeSelf","self","freeWindow","window","thisGlobal","root","Function","objectProto$5","symbolProto","nexTick","reject","rejectLimit","rejectSeries","some","Boolean","someLimit","ceil","timesLimit","all","any","forEach","forEachSeries","forEachLimit","forEachOf","forEachOfSeries","forEachOfLimit","inject","foldl","foldr","select","selectLimit","selectSeries","wrapSync"],"mappings":"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"} \ No newline at end of file
+{"version":3,"file":"build/dist/async.min.js","sources":["build/dist/async.js"],"names":["global","factory","exports","module","define","amd","async","this","apply","func","thisArg","args","length","call","isObject","value","type","isFunction","tag","objectToString","funcTag","genTag","toNumber","other","valueOf","replace","reTrim","isBinary","reIsBinary","test","reIsOctal","freeParseInt","slice","reIsBadHex","NAN","toInteger","INFINITY","sign","MAX_INTEGER","remainder","rest","start","TypeError","FUNC_ERROR_TEXT","nativeMax","undefined","arguments","index","array","Array","otherArgs","initialParams","fn","callback","pop","applyEach$1","eachfn","fns","go","that","_","cb","concat","noop","before","n","result","FUNC_ERROR_TEXT$1","once","baseProperty","key","object","isLength","MAX_SAFE_INTEGER","isArrayLike","getLength","getIterator","coll","iteratorSymbol","baseHas","hasOwnProperty","getPrototypeOf","baseKeys","nativeKeys","Object","baseTimes","iteratee","isObjectLike","isArrayLikeObject","isArguments","hasOwnProperty$1","propertyIsEnumerable","objectToString$1","argsTag","isString","isArray","objectToString$2","stringTag","indexKeys","String","isIndex","reIsUint","MAX_SAFE_INTEGER$1","isPrototype","Ctor","constructor","proto","prototype","objectProto$4","keys","isProto","indexes","skipIndexes","push","iterator","len","i","iterate","item","next","done","okeys","onlyOnce","Error","_eachOfLimit","limit","obj","nextElem","running","errored","replenish","elem","err","eachOfLimit","doLimit","iterable","asyncify","e","then","message","arrayEach","identity","baseCastFunction","createBaseFor","fromRight","keysFunc","props","baseForOwn","baseFor","forOwn","indexOfNaN","fromIndex","baseIndexOf","indexOf","nativeMax$1","auto","tasks","concurrency","enqueueTask","task","readyTasks","runTask","processQueue","runningTasks","results","run","shift","addListener","taskName","taskListeners","listeners","taskComplete","hasError","taskCallback","safeResults","val","rkey","taskFn","keys$$","numTasks","checkForDeadlocks","dep","dependencies","join","remainingDependencies","dependencyName","arrayMap","stackClear","__data__","map","eq","assocIndexOf","assocDelete","lastIndex","splice","stackDelete","data","assocGet","stackGet","get","assocHas","stackHas","has","isHostObject","toString","isNative","reIsNative","funcToString","reIsHostCtor","getNative","Hash","checkGlobal","mapClear","hash","Map","string","hashHas","nativeCreate","hasOwnProperty$3","hashDelete","isKeyable","mapDelete","hashGet","HASH_UNDEFINED","hasOwnProperty$4","mapGet","mapHas","assocSet","hashSet","HASH_UNDEFINED$1","mapSet","set","MapCache","values","clear","entry","stackSet","LARGE_ARRAY_SIZE","Stack","assignValue","objValue","hasOwnProperty$5","copyObjectWith","source","customizer","newValue","copyObject","baseAssign","cloneBuffer","buffer","isDeep","copy","copyArray","copySymbols","getSymbols","getTag","objectToString$3","initCloneArray","hasOwnProperty$6","input","cloneArrayBuffer","arrayBuffer","byteLength","Uint8Array","addMapEntry","pair","arrayReduce","accumulator","initAccum","mapToArray","size","forEach","cloneMap","cloneRegExp","regexp","reFlags","exec","addSetEntry","add","setToArray","cloneSet","cloneSymbol","symbol","symbolValueOf","cloneTypedArray","typedArray","byteOffset","initCloneByTag","arrayBufferTag$1","boolTag$1","dateTag$1","float32Tag$1","float64Tag$1","int8Tag$1","int16Tag$1","int32Tag$1","uint8Tag$1","uint8ClampedTag$1","uint16Tag$1","uint32Tag$1","mapTag$2","numberTag$1","stringTag$2","regexpTag$1","setTag$2","symbolTag$1","baseCreate","objectCreate","initCloneObject","getPrototypeOf$1","constant","baseClone","isFull","stack","isArr","getTag$1","isFunc","funcTag$1","genTag$1","isBuffer","objectTag","argsTag$1","cloneableTags","stacked","subValue","parseParams","match","argsRegex","split","autoInject","newTasks","newTask","taskCb","newArgs","params","name","queue","worker","payload","_insert","q","pos","started","idle","setImmediate$1","drain","unshift","process","_next","workers","removed","workersList","unsaturated","saturated","empty","paused","kill","pause","resume","resumeCount","Math","min","w","cargo","reduce","arr","memo","eachOfSeries","x","v","seq","newargs","nextargs","compose","reverse","concat$1","y","doParallel","eachOf","doSeries","_createTester","check","getResult","wrappedIteratee","_findGetResult","consoleFunc","console","error","during","truth","doDuring","calls","whilst","doWhilst","doUntil","_withoutIndex","eachLimit","ensureAsync","sync","innerArgs","notId","_filter","sort","a","b","doParallelLimit","forever","iterator$1","makeCallback","_asyncMap","isSymbol","objectToString$4","symbolTag$2","symbolToString","INFINITY$1","stringToPath","rePropName","number","quote","reEscapeChar","baseCastPath","isKey","reIsPlainProp","reIsDeepProp","last","baseSlice","end","baseGet","path","defaultValue","parent","hasPath","hasFunc","memoize","hasher","create","queues","memoized","l","unmemoized","_parallel","parallelLimit","queue$1","items","priorityQueue","_compareTasks","priority","_binarySearch","sequence","compare","beg","mid","createBaseEach","eachFunc","collection","baseEach","race","reduceRight","reversed","reject$1","series","retry","times","parseTimes","acc","t","DEFAULT_TIMES","interval","DEFAULT_INTERVAL","retryAttempt","isFinalAttempt","seriesCallback","retryInterval","setTimeout","opts","attempts","retryable","sortBy","comparator","left","right","criteria","timeout","asyncFn","miliseconds","injectedCallback","timedOut","originalCallback","clearTimeout","timer","timeoutCallback","code","origCallback","baseRange","step","nativeMax$2","nativeCeil","timeLimit","count","mapLimit","transform","k","unmemoize","until","waterfall","nextTask","taskIndex","objectProto","parseInt","max","Symbol","objectProto$1","objectProto$2","objectProto$3","Infinity","applyEach","applyEachSeries","apply$1","callArgs","arrayProto","reRegExpChar","objectProto$6","Function","hasOwnProperty$2","RegExp","objectProto$5","objectTypes","function","freeExports","nodeType","freeModule","freeGlobal","freeSelf","self","freeWindow","window","thisGlobal","root","objectProto$7","objectProto$8","objectProto$9","getOwnPropertySymbols","Set","WeakMap","mapTag$1","objectTag$1","setTag$1","weakMapTag$1","objectProto$10","funcToString$1","mapCtorString","setCtorString","weakMapCtorString","ctorString","objectProto$11","Symbol$1","symbolProto","objectTypes$1","freeExports$1","freeModule$1","moduleExports","Buffer","arrayTag","boolTag","dateTag","errorTag","mapTag","numberTag","regexpTag","setTag","stringTag$1","symbolTag","weakMapTag","arrayBufferTag","float32Tag","float64Tag","int8Tag","int16Tag","int32Tag","uint8Tag","uint8ClampedTag","uint16Tag","uint32Tag","_defer","_setImmediate","setImmediate","nextTick","concatSeries","constant$1","ignoredArgs","detect","detectLimit","detectSeries","dir","each","eachSeries","everyLimit","every","everySeries","filterLimit","filter","filterSeries","log","mapSeries","objectProto$12","symbolProto$1","parallel","rejectLimit","reject","rejectSeries","someLimit","Boolean","some","someSeries","ceil","timesSeries","timesLimit","all","any","forEachSeries","forEachLimit","forEachOf","forEachOfSeries","forEachOfLimit","inject","foldl","foldr","select","selectLimit","selectSeries","wrapSync","allLimit","allSeries","anyLimit","anySeries","find","findLimit","findSeries"],"mappings":"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"} \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644
index fbc58a1..0000000
--- a/gulpfile.js
+++ /dev/null
@@ -1,89 +0,0 @@
-'use strict';
-// This is used to generate individual packages for each async method
-
-var gulp = require('gulp');
-var path = require('path');
-var fs = require('fs-extra');
-var pkg = require('./package.json');
-var jsonFuture = require('json-future');
-var template = require('lodash.template');
-
-var moduleDeps = JSON.parse(template(fs.readFileSync('./support/dependencies.json').toString())({
- version: pkg.version}
- ));
-
-var MODULES_PATH = './lib/';
-
-function getFolders(dir) {
- return fs.readdirSync(dir)
- .filter(function(file) {
- return fs.statSync(path.join(dir, file)).isDirectory();
- });
-}
-
-function generatePackage(name) {
- function generateKeywords(name) {
- var keywords = [
- 'async',
- 'async-modularized'
- ];
-
- keywords.push(name);
- return keywords;
- }
-
- function generateDefaultFields(name) {
- var ORIGINAL_FIELDS = [
- 'author',
- 'version',
- 'repository',
- 'license'
- ];
-
- var structure = {
- name: 'async.' + name,
- description: 'async ' + name + 'method as module.',
- main: './index.js',
- repository: "async-js/async." + name
- };
-
- ORIGINAL_FIELDS.forEach(function(field) {
- structure[field] = pkg[field];
- });
-
- if (Object.keys(moduleDeps[name]).length > 0)
- structure.dependencies = moduleDeps[name];
-
- return structure;
- }
-
- var modulePackage = generateDefaultFields(name);
- modulePackage.keywords = generateKeywords(name);
- return modulePackage;
-}
-
-function generateReadme(name, dist) {
- var filepath = path.resolve('support/module_template.md');
- var tpl = fs.readFileSync(filepath).toString();
- tpl = template(tpl)({name: name});
- fs.writeFileSync(dist, tpl);
-}
-
-function copyMetaFiles(dist) {
- var files = ['.editorconfig', '.jscsrc', '.jshintrc', '.gitignore'];
-
- files.forEach(function(file) {
- var metafile = path.resolve(file);
- var distFile = path.resolve(dist, file);
- fs.copySync(metafile, distFile);
- });
-}
-
-gulp.task('package', function() {
- return getFolders(MODULES_PATH).map(function(module) {
- var dist = path.resolve(MODULES_PATH, module);
- jsonFuture.save(path.resolve(dist, 'package.json'), generatePackage(module));
- generateReadme(module, path.resolve(dist, 'README.md'));
- copyMetaFiles(dist);
- });
-});
diff --git a/lib/asyncify.js b/lib/asyncify.js
index f9f00e1..cf392e9 100644
--- a/lib/asyncify.js
+++ b/lib/asyncify.js
@@ -1,11 +1,10 @@
'use strict';
import isObject from 'lodash/isObject';
-import rest from 'lodash/rest';
+import initialParams from './internal/initialParams';
export default function asyncify(func) {
- return rest(function (args) {
- var callback = args.pop();
+ return initialParams(function (args, callback) {
var result;
try {
result = func.apply(this, args);
diff --git a/lib/auto.js b/lib/auto.js
index 0e9d108..afca933 100644
--- a/lib/auto.js
+++ b/lib/auto.js
@@ -1,66 +1,121 @@
'use strict';
import arrayEach from 'lodash/_arrayEach';
-import arrayEvery from 'lodash/_arrayEvery';
-import baseHas from 'lodash/_baseHas';
import forOwn from 'lodash/forOwn';
-import indexOf from 'lodash/indexOf';
+import indexOf from 'lodash/_baseIndexOf';
import isArray from 'lodash/isArray';
import okeys from 'lodash/keys';
import noop from 'lodash/noop';
-import once from 'lodash/once';
+import once from './internal/once';
import rest from 'lodash/rest';
-import setImmediate from './internal/setImmediate';
+import onlyOnce from './internal/onlyOnce';
export default function (tasks, concurrency, callback) {
- if (typeof arguments[1] === 'function') {
+ if (typeof concurrency === 'function') {
// concurrency is optional, shift the args.
callback = concurrency;
concurrency = null;
}
callback = once(callback || noop);
var keys = okeys(tasks);
- var remainingTasks = keys.length;
- if (!remainingTasks) {
+ var numTasks = keys.length;
+ if (!numTasks) {
return callback(null);
}
if (!concurrency) {
- concurrency = remainingTasks;
+ concurrency = numTasks;
}
var results = {};
var runningTasks = 0;
var hasError = false;
- var listeners = [];
+ var listeners = {};
- function addListener(fn) {
- listeners.unshift(fn);
+ var readyTasks = [];
+
+
+ forOwn(tasks, function (task, key) {
+ if (!isArray(task)) {
+ // no dependencies
+ enqueueTask(key, [task]);
+ return;
+ }
+
+ var dependencies = task.slice(0, task.length - 1);
+ var remainingDependencies = dependencies.length;
+
+ checkForDeadlocks();
+
+ function checkForDeadlocks() {
+ var len = dependencies.length;
+ var dep;
+ while (len--) {
+ if (!(dep = tasks[dependencies[len]])) {
+ throw new Error('async.auto task `' + key +
+ '` has non-existent dependency in ' +
+ dependencies.join(', '));
+ }
+ if (isArray(dep) && indexOf(dep, key, 0) >= 0) {
+ throw new Error('async.auto task `' + key +
+ '`Has cyclic dependencies');
+ }
+ }
+ }
+
+ arrayEach(dependencies, function (dependencyName) {
+ addListener(dependencyName, function () {
+ remainingDependencies--;
+ if (remainingDependencies === 0) {
+ enqueueTask(key, task);
+ }
+ });
+ });
+ });
+
+ processQueue();
+
+
+ function enqueueTask(key, task) {
+ readyTasks.push(function () {
+ runTask(key, task);
+ });
}
- function removeListener(fn) {
- var idx = indexOf(listeners, fn);
- if (idx >= 0) listeners.splice(idx, 1);
+ function processQueue() {
+ if (readyTasks.length === 0 && runningTasks === 0) {
+ return callback(null, results);
+ }
+ while(readyTasks.length && runningTasks < concurrency) {
+ var run = readyTasks.shift();
+ run();
+ }
+
+ }
+
+ function addListener(taskName, fn) {
+ var taskListeners = listeners[taskName];
+ if (!taskListeners) {
+ taskListeners = listeners[taskName] = [];
+ }
+
+ taskListeners.push(fn);
}
- function taskComplete() {
- remainingTasks--;
- arrayEach(listeners.slice(), function (fn) {
+ function taskComplete(taskName) {
+ var taskListeners = listeners[taskName] || [];
+ arrayEach(taskListeners, function (fn) {
fn();
});
+ processQueue();
}
- addListener(function () {
- if (!remainingTasks) {
- callback(null, results);
- }
- });
- arrayEach(keys, function (k) {
+ function runTask(key, task) {
if (hasError) return;
- var task = isArray(tasks[k]) ? tasks[k]: [tasks[k]];
- var taskCallback = rest(function(err, args) {
+
+ var taskCallback = onlyOnce(rest(function(err, args) {
runningTasks--;
if (args.length <= 1) {
args = args[0];
@@ -70,66 +125,25 @@ export default function (tasks, concurrency, callback) {
forOwn(results, function(val, rkey) {
safeResults[rkey] = val;
});
- safeResults[k] = args;
+ safeResults[key] = args;
hasError = true;
listeners = [];
callback(err, safeResults);
+ } else {
+ results[key] = args;
+ taskComplete(key);
}
- else {
- results[k] = args;
- setImmediate(taskComplete);
- }
- });
+ }));
- var requires = task.slice(0, task.length - 1);
-
- checkForDeadlocks();
-
- if (ready()) {
- startNext();
+ runningTasks++;
+ var taskFn = task[task.length - 1];
+ if (task.length > 1) {
+ taskFn(results, taskCallback);
} else {
- addListener(listener);
- }
-
- function checkForDeadlocks() {
- var len = requires.length;
- var dep;
- while (len--) {
- if (!(dep = tasks[requires[len]])) {
- throw new Error('Has non-existent dependency in ' +
- requires.join(', '));
- }
- if (isArray(dep) && indexOf(dep, k) >= 0) {
- throw new Error('Has cyclic dependencies');
- }
- }
- }
-
- function ready() {
- return runningTasks < concurrency &&
- !baseHas(results, k) &&
- !hasError &&
- arrayEvery(requires, function (x) {
- return baseHas(results, x);
- });
+ taskFn(taskCallback);
}
+ }
- function startNext() {
- runningTasks++;
- var taskFn = task[task.length - 1];
- if (requires.length > 0) {
- taskFn(results, taskCallback);
- } else {
- taskFn(taskCallback);
- }
- }
- function listener() {
- if (ready()) {
- removeListener(listener);
- startNext();
- }
- }
- });
}
diff --git a/lib/autoInject.js b/lib/autoInject.js
new file mode 100644
index 0000000..9259487
--- /dev/null
+++ b/lib/autoInject.js
@@ -0,0 +1,46 @@
+import auto from './auto';
+import forOwn from 'lodash/forOwn';
+import arrayMap from 'lodash/_arrayMap';
+import clone from 'lodash/_copyArray';
+import isArray from 'lodash/isArray';
+
+var argsRegex = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
+
+function parseParams(func) {
+ return func.toString().match(argsRegex)[1].split(/\s*\,\s*/);
+}
+
+export default function autoInject(tasks, callback) {
+ var newTasks = {};
+
+ forOwn(tasks, function (taskFn, key) {
+ var params;
+
+ if (isArray(taskFn)) {
+ params = clone(taskFn);
+ taskFn = params.pop();
+
+ newTasks[key] = params.concat(newTask);
+ } else if (taskFn.length === 0) {
+ throw new Error("autoInject task functions require explicit parameters.");
+ } else if (taskFn.length === 1) {
+ // no dependencies, use the function as-is
+ newTasks[key] = taskFn;
+ } else {
+ params = parseParams(taskFn);
+ params.pop();
+
+ newTasks[key] = params.concat(newTask);
+ }
+
+ function newTask(results, taskCb) {
+ var newArgs = arrayMap(params, function (name) {
+ return results[name];
+ });
+ newArgs.push(taskCb);
+ taskFn.apply(null, newArgs);
+ }
+ });
+
+ auto(newTasks, callback);
+}
diff --git a/lib/constant.js b/lib/constant.js
index 706507f..133b244 100644
--- a/lib/constant.js
+++ b/lib/constant.js
@@ -1,10 +1,11 @@
'use strict';
import rest from 'lodash/rest';
+import initialParams from './internal/initialParams';
export default rest(function(values) {
var args = [null].concat(values);
- return function (cb) {
- return cb.apply(this, args);
- };
+ return initialParams(function (ignoredArgs, callback) {
+ return callback.apply(this, args);
+ });
});
diff --git a/lib/doDuring.js b/lib/doDuring.js
index c13e62b..73504c2 100644
--- a/lib/doDuring.js
+++ b/lib/doDuring.js
@@ -2,11 +2,11 @@
import during from './during';
-export default function doDuring(iterator, test, cb) {
+export default function doDuring(iteratee, test, cb) {
var calls = 0;
during(function(next) {
if (calls++ < 1) return next(null, true);
test.apply(this, arguments);
- }, iterator, cb);
+ }, iteratee, cb);
}
diff --git a/lib/doUntil.js b/lib/doUntil.js
index 3bc783f..d5f2b83 100644
--- a/lib/doUntil.js
+++ b/lib/doUntil.js
@@ -2,8 +2,8 @@
import doWhilst from './doWhilst';
-export default function doUntil(iterator, test, cb) {
- return doWhilst(iterator, function() {
+export default function doUntil(iteratee, test, cb) {
+ return doWhilst(iteratee, function() {
return !test.apply(this, arguments);
}, cb);
}
diff --git a/lib/doWhilst.js b/lib/doWhilst.js
index b05d1d8..1cd56a7 100644
--- a/lib/doWhilst.js
+++ b/lib/doWhilst.js
@@ -2,9 +2,9 @@
import whilst from './whilst';
-export default function doWhilst(iterator, test, cb) {
+export default function doWhilst(iteratee, test, cb) {
var calls = 0;
return whilst(function() {
return ++calls <= 1 || test.apply(this, arguments);
- }, iterator, cb);
+ }, iteratee, cb);
}
diff --git a/lib/during.js b/lib/during.js
index 6b7c4d4..013a3dc 100644
--- a/lib/during.js
+++ b/lib/during.js
@@ -3,7 +3,7 @@
import noop from 'lodash/noop';
import rest from 'lodash/rest';
-export default function during(test, iterator, cb) {
+export default function during(test, iteratee, cb) {
cb = cb || noop;
var next = rest(function(err, args) {
@@ -18,7 +18,7 @@ export default function during(test, iterator, cb) {
var check = function(err, truth) {
if (err) return cb(err);
if (!truth) return cb(null);
- iterator(next);
+ iteratee(next);
};
test(check);
diff --git a/lib/eachLimit.js b/lib/eachLimit.js
index 5009cc3..74965a8 100644
--- a/lib/eachLimit.js
+++ b/lib/eachLimit.js
@@ -4,6 +4,6 @@ import eachOfLimit from './internal/eachOfLimit';
import withoutIndex from './internal/withoutIndex';
-export default function eachLimit(arr, limit, iterator, cb) {
- return eachOfLimit(limit)(arr, withoutIndex(iterator), cb);
+export default function eachLimit(arr, limit, iteratee, cb) {
+ return eachOfLimit(limit)(arr, withoutIndex(iteratee), cb);
}
diff --git a/lib/eachOfLimit.js b/lib/eachOfLimit.js
index e381474..b6ca139 100644
--- a/lib/eachOfLimit.js
+++ b/lib/eachOfLimit.js
@@ -2,6 +2,6 @@
import _eachOfLimit from './internal/eachOfLimit';
-export default function eachOfLimit(obj, limit, iterator, cb) {
- _eachOfLimit(limit)(obj, iterator, cb);
+export default function eachOfLimit(obj, limit, iteratee, cb) {
+ _eachOfLimit(limit)(obj, iteratee, cb);
}
diff --git a/lib/ensureAsync.js b/lib/ensureAsync.js
index 4f4f762..091f3ae 100644
--- a/lib/ensureAsync.js
+++ b/lib/ensureAsync.js
@@ -1,12 +1,10 @@
'use strict';
-import rest from 'lodash/rest';
-
import setImmediate from './internal/setImmediate';
+import initialParams from './internal/initialParams';
export default function ensureAsync(fn) {
- return rest(function (args) {
- var callback = args.pop();
+ return initialParams(function (args, callback) {
var sync = true;
args.push(function () {
var innerArgs = arguments;
diff --git a/lib/everySeries.js b/lib/everySeries.js
new file mode 100644
index 0000000..0b3db2c
--- /dev/null
+++ b/lib/everySeries.js
@@ -0,0 +1,6 @@
+'use strict';
+
+import everyLimit from './everyLimit';
+import doLimit from './internal/doLimit';
+
+export default doLimit(everyLimit, 1);
diff --git a/lib/index.js b/lib/index.js
index 2e27f25..6832662 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -5,6 +5,7 @@ import applyEachSeries from './applyEachSeries';
import apply from './apply';
import asyncify from './asyncify';
import auto from './auto';
+import autoInject from './autoInject';
import cargo from './cargo';
import compose from './compose';
import concat from './concat';
@@ -27,6 +28,7 @@ import eachSeries from './eachSeries';
import ensureAsync from './ensureAsync';
import every from './every';
import everyLimit from './everyLimit';
+import everySeries from './everySeries';
import filter from './filter';
import filterLimit from './filterLimit';
import filterSeries from './filterSeries';
@@ -45,16 +47,21 @@ import queue from './queue';
import race from './race';
import reduce from './reduce';
import reduceRight from './reduceRight';
+import reflect from './reflect';
import reject from './reject';
+import reflectAll from './reflectAll';
import rejectLimit from './rejectLimit';
import rejectSeries from './rejectSeries';
import retry from './retry';
+import retryable from './retryable';
import seq from './seq';
import series from './series';
import setImmediate from './setImmediate';
import some from './some';
import someLimit from './someLimit';
+import someSeries from './someSeries';
import sortBy from './sortBy';
+import timeout from './timeout';
import times from './times';
import timesLimit from './timesLimit';
import timesSeries from './timesSeries';
@@ -70,6 +77,7 @@ export default {
apply: apply,
asyncify: asyncify,
auto: auto,
+ autoInject: autoInject,
cargo: cargo,
compose: compose,
concat: concat,
@@ -92,6 +100,7 @@ export default {
ensureAsync: ensureAsync,
every: every,
everyLimit: everyLimit,
+ everySeries: everySeries,
filter: filter,
filterLimit: filterLimit,
filterSeries: filterSeries,
@@ -110,16 +119,21 @@ export default {
race: race,
reduce: reduce,
reduceRight: reduceRight,
+ reflect: reflect,
+ reflectAll: reflectAll,
reject: reject,
rejectLimit: rejectLimit,
rejectSeries: rejectSeries,
retry: retry,
+ retryable: retryable,
seq: seq,
series: series,
setImmediate: setImmediate,
some: some,
someLimit: someLimit,
+ someSeries: someSeries,
sortBy: sortBy,
+ timeout: timeout,
times: times,
timesLimit: timesLimit,
timesSeries: timesSeries,
@@ -153,6 +167,7 @@ export {
apply as apply,
asyncify as asyncify,
auto as auto,
+ autoInject as autoInject,
cargo as cargo,
compose as compose,
concat as concat,
@@ -175,6 +190,7 @@ export {
ensureAsync as ensureAsync,
every as every,
everyLimit as everyLimit,
+ everySeries as everySeries,
filter as filter,
filterLimit as filterLimit,
filterSeries as filterSeries,
@@ -193,16 +209,21 @@ export {
race as race,
reduce as reduce,
reduceRight as reduceRight,
+ reflect as reflect,
+ reflectAll as reflectAll,
reject as reject,
rejectLimit as rejectLimit,
rejectSeries as rejectSeries,
retry as retry,
+ retryable as retryable,
seq as seq,
series as series,
setImmediate as setImmediate,
some as some,
someLimit as someLimit,
+ someSeries as someSeries,
sortBy as sortBy,
+ timeout as timeout,
times as times,
timesLimit as timesLimit,
timesSeries as timesSeries,
@@ -214,7 +235,14 @@ export {
// Aliases
every as all,
+ everyLimit as allLimit,
+ everySeries as allSeries,
some as any,
+ someLimit as anyLimit,
+ someSeries as anySeries,
+ detect as find,
+ detectLimit as findLimit,
+ detectSeries as findSeries,
each as forEach,
eachSeries as forEachSeries,
eachLimit as forEachLimit,
diff --git a/lib/internal/applyEach.js b/lib/internal/applyEach.js
index 25bcce1..47710d4 100644
--- a/lib/internal/applyEach.js
+++ b/lib/internal/applyEach.js
@@ -1,12 +1,12 @@
'use strict';
import rest from 'lodash/rest';
+import initialParams from './initialParams';
export default function applyEach(eachfn) {
return rest(function(fns, args) {
- var go = rest(function(args) {
+ var go = initialParams(function(args, callback) {
var that = this;
- var callback = args.pop();
return eachfn(fns, function (fn, _, cb) {
fn.apply(that, args.concat([cb]));
},
diff --git a/lib/internal/createTester.js b/lib/internal/createTester.js
index 282ef87..ac38bf7 100644
--- a/lib/internal/createTester.js
+++ b/lib/internal/createTester.js
@@ -1,7 +1,8 @@
'use strict';
+import noop from 'lodash/noop';
export default function _createTester(eachfn, check, getResult) {
- return function(arr, limit, iterator, cb) {
+ return function(arr, limit, iteratee, cb) {
function done(err) {
if (cb) {
if (err) {
@@ -11,27 +12,29 @@ export default function _createTester(eachfn, check, getResult) {
}
}
}
- function iteratee(x, _, callback) {
+ function wrappedIteratee(x, _, callback) {
if (!cb) return callback();
- iterator(x, function (err, v) {
+ iteratee(x, function (err, v) {
if (cb) {
if (err) {
cb(err);
- cb = iterator = false;
+ cb = iteratee = false;
} else if (check(v)) {
cb(null, getResult(true, x));
- cb = iterator = false;
+ cb = iteratee = false;
}
}
callback();
});
}
if (arguments.length > 3) {
- eachfn(arr, limit, iteratee, done);
+ cb = cb || noop;
+ eachfn(arr, limit, wrappedIteratee, done);
} else {
- cb = iterator;
- iterator = limit;
- eachfn(arr, iteratee, done);
+ cb = iteratee;
+ cb = cb || noop;
+ iteratee = limit;
+ eachfn(arr, wrappedIteratee, done);
}
};
}
diff --git a/lib/internal/doLimit.js b/lib/internal/doLimit.js
index 16bfa42..61a609f 100644
--- a/lib/internal/doLimit.js
+++ b/lib/internal/doLimit.js
@@ -1,7 +1,7 @@
'use strict';
export default function doLimit(fn, limit) {
- return function (iterable, iterator, callback) {
- return fn(iterable, limit, iterator, callback);
+ return function (iterable, iteratee, callback) {
+ return fn(iterable, limit, iteratee, callback);
};
}
diff --git a/lib/internal/doParallel.js b/lib/internal/doParallel.js
index 19c90fc..0d08bae 100644
--- a/lib/internal/doParallel.js
+++ b/lib/internal/doParallel.js
@@ -3,7 +3,7 @@
import eachOf from '../eachOf';
export default function doParallel(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOf, obj, iterator, callback);
+ return function (obj, iteratee, callback) {
+ return fn(eachOf, obj, iteratee, callback);
};
}
diff --git a/lib/internal/doParallelLimit.js b/lib/internal/doParallelLimit.js
index 0c3bcf7..3f17510 100644
--- a/lib/internal/doParallelLimit.js
+++ b/lib/internal/doParallelLimit.js
@@ -3,7 +3,7 @@
import eachOfLimit from './eachOfLimit';
export default function doParallelLimit(fn) {
- return function (obj, limit, iterator, callback) {
- return fn(eachOfLimit(limit), obj, iterator, callback);
+ return function (obj, limit, iteratee, callback) {
+ return fn(eachOfLimit(limit), obj, iteratee, callback);
};
}
diff --git a/lib/internal/doSeries.js b/lib/internal/doSeries.js
index c7f1d99..0a0f3bd 100644
--- a/lib/internal/doSeries.js
+++ b/lib/internal/doSeries.js
@@ -3,7 +3,7 @@
import eachOfSeries from '../eachOfSeries';
export default function doSeries(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOfSeries, obj, iterator, callback);
+ return function (obj, iteratee, callback) {
+ return fn(eachOfSeries, obj, iteratee, callback);
};
}
diff --git a/lib/internal/eachOfLimit.js b/lib/internal/eachOfLimit.js
index be1eab8..b5ed217 100644
--- a/lib/internal/eachOfLimit.js
+++ b/lib/internal/eachOfLimit.js
@@ -1,16 +1,16 @@
'use strict';
import noop from 'lodash/noop';
-import once from 'lodash/once';
+import once from './once';
-import keyIterator from './keyIterator';
+import iterator from './iterator';
import onlyOnce from './onlyOnce';
export default function _eachOfLimit(limit) {
- return function (obj, iterator, callback) {
+ return function (obj, iteratee, callback) {
callback = once(callback || noop);
obj = obj || [];
- var nextKey = keyIterator(obj);
+ var nextElem = iterator(obj);
if (limit <= 0) {
return callback(null);
}
@@ -24,8 +24,8 @@ export default function _eachOfLimit(limit) {
}
while (running < limit && !errored) {
- var key = nextKey();
- if (key === null) {
+ var elem = nextElem();
+ if (elem === null) {
done = true;
if (running <= 0) {
callback(null);
@@ -33,7 +33,7 @@ export default function _eachOfLimit(limit) {
return;
}
running += 1;
- iterator(obj[key], key, onlyOnce(function (err) {
+ iteratee(elem.value, elem.key, onlyOnce(function (err) {
running -= 1;
if (err) {
callback(err);
diff --git a/lib/internal/filter.js b/lib/internal/filter.js
index 8b1de9f..a8c883b 100644
--- a/lib/internal/filter.js
+++ b/lib/internal/filter.js
@@ -3,10 +3,10 @@
import arrayMap from 'lodash/_arrayMap';
import property from 'lodash/_baseProperty';
-export default function _filter(eachfn, arr, iterator, callback) {
+export default function _filter(eachfn, arr, iteratee, callback) {
var results = [];
eachfn(arr, function (x, index, callback) {
- iterator(x, function (err, v) {
+ iteratee(x, function (err, v) {
if (err) {
callback(err);
}
diff --git a/lib/internal/getIterator.js b/lib/internal/getIterator.js
new file mode 100644
index 0000000..87860f4
--- /dev/null
+++ b/lib/internal/getIterator.js
@@ -0,0 +1,5 @@
+var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator;
+
+export default function (coll) {
+ return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol]();
+}
diff --git a/lib/internal/initialParams.js b/lib/internal/initialParams.js
new file mode 100644
index 0000000..635caba
--- /dev/null
+++ b/lib/internal/initialParams.js
@@ -0,0 +1,8 @@
+import rest from 'lodash/rest';
+
+export default function (fn) {
+ return rest(function (args/*..., callback*/) {
+ var callback = args.pop();
+ fn(args, callback);
+ });
+}
diff --git a/lib/internal/iterator.js b/lib/internal/iterator.js
new file mode 100644
index 0000000..8b233e1
--- /dev/null
+++ b/lib/internal/iterator.js
@@ -0,0 +1,36 @@
+'use strict';
+
+import isArrayLike from 'lodash/isArrayLike';
+import getIterator from './getIterator';
+import keys from 'lodash/keys';
+
+export default function iterator(coll) {
+ var i = -1;
+ var len;
+ if (isArrayLike(coll)) {
+ len = coll.length;
+ return function next() {
+ i++;
+ return i < len ? {value: coll[i], key: i} : null;
+ };
+ }
+
+ var iterate = getIterator(coll);
+ if (iterate) {
+ return function next() {
+ var item = iterate.next();
+ if (item.done)
+ return null;
+ i++;
+ return {value: item.value, key: i};
+ };
+ }
+
+ var okeys = keys(coll);
+ len = okeys.length;
+ return function next() {
+ i++;
+ var key = okeys[i];
+ return i < len ? {value: coll[key], key: key} : null;
+ };
+}
diff --git a/lib/internal/keyIterator.js b/lib/internal/keyIterator.js
deleted file mode 100644
index 0e2b0c3..0000000
--- a/lib/internal/keyIterator.js
+++ /dev/null
@@ -1,23 +0,0 @@
-'use strict';
-
-import isArrayLike from 'lodash/isArrayLike';
-import keys from 'lodash/keys';
-
-export default function keyIterator(coll) {
- var i = -1;
- var len;
- if (isArrayLike(coll)) {
- len = coll.length;
- return function next() {
- i++;
- return i < len ? i : null;
- };
- } else {
- var okeys = keys(coll);
- len = okeys.length;
- return function next() {
- i++;
- return i < len ? okeys[i] : null;
- };
- }
-}
diff --git a/lib/internal/map.js b/lib/internal/map.js
index a7c19ac..959138d 100644
--- a/lib/internal/map.js
+++ b/lib/internal/map.js
@@ -1,15 +1,16 @@
'use strict';
import isArrayLike from 'lodash/isArrayLike';
+import getIterator from './getIterator';
import noop from 'lodash/noop';
-import once from 'lodash/once';
+import once from './once';
-export default function _asyncMap(eachfn, arr, iterator, callback) {
+export default function _asyncMap(eachfn, arr, iteratee, callback) {
callback = once(callback || noop);
arr = arr || [];
- var results = isArrayLike(arr) ? [] : {};
+ var results = isArrayLike(arr) || getIterator(arr) ? [] : {};
eachfn(arr, function (value, index, callback) {
- iterator(value, function (err, v) {
+ iteratee(value, function (err, v) {
results[index] = v;
callback(err);
});
diff --git a/lib/internal/once.js b/lib/internal/once.js
new file mode 100644
index 0000000..11678dc
--- /dev/null
+++ b/lib/internal/once.js
@@ -0,0 +1,7 @@
+export default function once(fn) {
+ return function () {
+ if (fn === null) return;
+ fn.apply(this, arguments);
+ fn = null;
+ };
+}
diff --git a/lib/internal/queue.js b/lib/internal/queue.js
index 3e7eb1e..9a1f77f 100644
--- a/lib/internal/queue.js
+++ b/lib/internal/queue.js
@@ -42,12 +42,6 @@ export default function queue(worker, concurrency, payload) {
q.tasks.push(item);
}
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- if (q.tasks.length <= (q.concurrency - q.buffer) ) {
- q.unsaturated();
- }
});
setImmediate(q.process);
}
@@ -55,6 +49,7 @@ export default function queue(worker, concurrency, payload) {
return function(){
workers -= 1;
+
var removed = false;
var args = arguments;
arrayEach(tasks, function (task) {
@@ -67,6 +62,11 @@ export default function queue(worker, concurrency, payload) {
task.callback.apply(task, args);
});
+
+ if (workers <= (q.concurrency - q.buffer) ) {
+ q.unsaturated();
+ }
+
if (q.tasks.length + workers === 0) {
q.drain();
}
@@ -111,8 +111,15 @@ export default function queue(worker, concurrency, payload) {
}
workers += 1;
workersList.push(tasks[0]);
+
+ if (workers === q.concurrency) {
+ q.saturated();
+ }
+
var cb = onlyOnce(_next(q, tasks));
worker(data, cb);
+
+
}
},
length: function () {
diff --git a/lib/internal/reject.js b/lib/internal/reject.js
index 708e810..4a22a4e 100644
--- a/lib/internal/reject.js
+++ b/lib/internal/reject.js
@@ -2,9 +2,9 @@
import filter from './filter';
-export default function reject(eachfn, arr, iterator, callback) {
+export default function reject(eachfn, arr, iteratee, callback) {
filter(eachfn, arr, function(value, cb) {
- iterator(value, function(err, v) {
+ iteratee(value, function(err, v) {
if (err) {
cb(err);
} else {
diff --git a/lib/internal/setImmediate.js b/lib/internal/setImmediate.js
index c02ad71..7d15249 100644
--- a/lib/internal/setImmediate.js
+++ b/lib/internal/setImmediate.js
@@ -1,19 +1,21 @@
'use strict';
+import rest from 'lodash/rest';
var _setImmediate = typeof setImmediate === 'function' && setImmediate;
-var _delay;
+var _defer;
if (_setImmediate) {
- _delay = function(fn) {
- // not a direct alias for IE10 compatibility
- _setImmediate(fn);
- };
+ _defer = _setImmediate;
} else if (typeof process === 'object' && typeof process.nextTick === 'function') {
- _delay = process.nextTick;
+ _defer = process.nextTick;
} else {
- _delay = function(fn) {
+ _defer = function(fn) {
setTimeout(fn, 0);
};
}
-export default _delay;
+export default rest(function (fn, args) {
+ _defer(function () {
+ fn.apply(null, args);
+ });
+});
diff --git a/lib/internal/withoutIndex.js b/lib/internal/withoutIndex.js
index f163ff3..8cfbfa6 100644
--- a/lib/internal/withoutIndex.js
+++ b/lib/internal/withoutIndex.js
@@ -1,7 +1,7 @@
'use strict';
-export default function _withoutIndex(iterator) {
+export default function _withoutIndex(iteratee) {
return function (value, index, callback) {
- return iterator(value, callback);
+ return iteratee(value, callback);
};
}
diff --git a/lib/memoize.js b/lib/memoize.js
index 30b989c..d1af636 100644
--- a/lib/memoize.js
+++ b/lib/memoize.js
@@ -2,16 +2,19 @@
import identity from 'lodash/identity';
import rest from 'lodash/rest';
-import has from 'lodash/has';
import setImmediate from './internal/setImmediate';
+import initialParams from './internal/initialParams';
+
+function has(obj, key) {
+ return key in obj;
+}
export default function memoize(fn, hasher) {
var memo = Object.create(null);
var queues = Object.create(null);
hasher = hasher || identity;
- var memoized = rest(function memoized(args) {
- var callback = args.pop();
+ var memoized = initialParams(function memoized(args, callback) {
var key = hasher.apply(null, args);
if (has(memo, key)) {
setImmediate(function() {
diff --git a/lib/nextTick.js b/lib/nextTick.js
index b61a8b4..05d9555 100644
--- a/lib/nextTick.js
+++ b/lib/nextTick.js
@@ -2,6 +2,4 @@
import setImmediate from './internal/setImmediate';
-var nexTick = typeof process === 'object' && typeof process.nextTick === 'function' ? process.nextTick : setImmediate;
-
-export default nexTick;
+export default setImmediate;
diff --git a/lib/race.js b/lib/race.js
index 4a5f8a5..b89a5db 100644
--- a/lib/race.js
+++ b/lib/race.js
@@ -1,14 +1,15 @@
'use strict';
import isArray from 'lodash/isArray';
+import each from 'lodash/each';
import noop from 'lodash/noop';
-import once from 'lodash/once';
+import once from './internal/once';
export default function race(tasks, cb) {
cb = once(cb || noop);
if (!isArray(tasks)) return cb(new TypeError('First argument to race must be an array of functions'));
if (!tasks.length) return cb();
- for (let i = 0; i < tasks.length; i++) {
- tasks[i](cb);
- }
+ each(tasks, function (task) {
+ task(cb);
+ });
}
diff --git a/lib/reduce.js b/lib/reduce.js
index 51b736a..675ed8f 100644
--- a/lib/reduce.js
+++ b/lib/reduce.js
@@ -2,9 +2,9 @@
import eachOfSeries from './eachOfSeries';
-export default function reduce(arr, memo, iterator, cb) {
+export default function reduce(arr, memo, iteratee, cb) {
eachOfSeries(arr, function(x, i, cb) {
- iterator(memo, x, function(err, v) {
+ iteratee(memo, x, function(err, v) {
memo = v;
cb(err);
});
diff --git a/lib/reduceRight.js b/lib/reduceRight.js
index 730e320..f79f18f 100644
--- a/lib/reduceRight.js
+++ b/lib/reduceRight.js
@@ -4,7 +4,7 @@ import reduce from './reduce';
var slice = Array.prototype.slice;
-export default function reduceRight (arr, memo, iterator, cb) {
+export default function reduceRight (arr, memo, iteratee, cb) {
var reversed = slice.call(arr).reverse();
- reduce(reversed, memo, iterator, cb);
+ reduce(reversed, memo, iteratee, cb);
}
diff --git a/lib/reflect.js b/lib/reflect.js
new file mode 100644
index 0000000..2711254
--- /dev/null
+++ b/lib/reflect.js
@@ -0,0 +1,26 @@
+import initialParams from './internal/initialParams';
+import rest from 'lodash/rest';
+
+export default function reflect(fn) {
+ return initialParams(function reflectOn(args, reflectCallback) {
+ args.push(rest(function callback(err, cbArgs) {
+ if (err) {
+ reflectCallback(null, {
+ error: err
+ });
+ } else {
+ var value = null;
+ if (cbArgs.length === 1) {
+ value = cbArgs[0];
+ } else if (cbArgs.length > 1) {
+ value = cbArgs;
+ }
+ reflectCallback(null, {
+ value: value
+ });
+ }
+ }));
+
+ return fn.apply(this, args);
+ });
+}
diff --git a/lib/reflectAll.js b/lib/reflectAll.js
new file mode 100644
index 0000000..c4ecd9f
--- /dev/null
+++ b/lib/reflectAll.js
@@ -0,0 +1,7 @@
+'use strict';
+
+import reflect from './reflect';
+
+export default function reflectAll(tasks) {
+ return tasks.map(reflect);
+}
diff --git a/lib/retry.js b/lib/retry.js
index 506a424..aecd07f 100644
--- a/lib/retry.js
+++ b/lib/retry.js
@@ -1,12 +1,12 @@
'use strict';
import series from './series';
+import noop from 'lodash/noop';
export default function retry(times, task, callback) {
var DEFAULT_TIMES = 5;
var DEFAULT_INTERVAL = 0;
- var attempts = [];
var opts = {
times: DEFAULT_TIMES,
@@ -14,64 +14,62 @@ export default function retry(times, task, callback) {
};
function parseTimes(acc, t) {
- if (typeof t === 'number') {
- acc.times = parseInt(t, 10) || DEFAULT_TIMES;
- } else if (typeof t === 'object') {
- acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
- acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
+ if (typeof t === 'object') {
+ acc.times = +t.times || DEFAULT_TIMES;
+ acc.interval = +t.interval || DEFAULT_INTERVAL;
+ } else if (typeof t === 'number' || typeof t === 'string') {
+ acc.times = +t || DEFAULT_TIMES;
} else {
- throw new Error('Unsupported argument type for \'times\': ' + typeof t);
+ throw new Error("Invalid arguments for async.retry");
}
}
- var length = arguments.length;
- if (length < 1 || length > 3) {
- throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
- } else if (length <= 2 && typeof times === 'function') {
- callback = task;
+
+ if (arguments.length < 3 && typeof times === 'function') {
+ callback = task || noop;
task = times;
- }
- if (typeof times !== 'function') {
+ } else {
parseTimes(opts, times);
+ callback = callback || noop;
}
- opts.callback = callback;
- opts.task = task;
- function wrappedTask(wrappedCallback, wrappedResults) {
- function retryAttempt(task, finalAttempt) {
- return function(seriesCallback) {
- task(function(err, result) {
- seriesCallback(!err || finalAttempt, {
- err: err,
- result: result
- });
- }, wrappedResults);
- };
- }
- function retryInterval(interval) {
- return function(seriesCallback) {
- setTimeout(function() {
- seriesCallback(null);
- }, interval);
- };
- }
+ if (typeof task !== 'function') {
+ throw new Error("Invalid arguments for async.retry");
+ }
- while (opts.times) {
- var finalAttempt = !(opts.times -= 1);
- attempts.push(retryAttempt(opts.task, finalAttempt));
- if (!finalAttempt && opts.interval > 0) {
- attempts.push(retryInterval(opts.interval));
- }
+ var attempts = [];
+ while (opts.times) {
+ var isFinalAttempt = !(opts.times -= 1);
+ attempts.push(retryAttempt(isFinalAttempt));
+ if (!isFinalAttempt && opts.interval > 0) {
+ attempts.push(retryInterval(opts.interval));
}
+ }
+
+ series(attempts, function(done, data) {
+ data = data[data.length - 1];
+ callback(data.err, data.result);
+ });
- series(attempts, function(done, data) {
- data = data[data.length - 1];
- (wrappedCallback || opts.callback)(data.err, data.result);
- });
+
+ function retryAttempt(isFinalAttempt) {
+ return function(seriesCallback) {
+ task(function(err, result) {
+ seriesCallback(!err || isFinalAttempt, {
+ err: err,
+ result: result
+ });
+ });
+ };
}
- // If a callback is passed, run this as a controll flow
- return opts.callback ? wrappedTask() : wrappedTask;
+ function retryInterval(interval) {
+ return function(seriesCallback) {
+ setTimeout(function() {
+ seriesCallback(null);
+ }, interval);
+ };
+ }
}
diff --git a/lib/retryable.js b/lib/retryable.js
new file mode 100644
index 0000000..f01d9b9
--- /dev/null
+++ b/lib/retryable.js
@@ -0,0 +1,18 @@
+import retry from './retry';
+import initialParams from './internal/initialParams';
+
+export default function (opts, task) {
+ if (!task) {
+ task = opts;
+ opts = null;
+ }
+ return initialParams(function (args, callback) {
+ function taskFn(cb) {
+ task.apply(null, args.concat([cb]));
+ }
+
+ if (opts) retry(opts, taskFn, callback);
+ else retry(taskFn, callback);
+
+ });
+}
diff --git a/lib/someSeries.js b/lib/someSeries.js
new file mode 100644
index 0000000..a5fc97c
--- /dev/null
+++ b/lib/someSeries.js
@@ -0,0 +1,6 @@
+'use strict';
+
+import someLimit from './someLimit';
+import doLimit from './internal/doLimit';
+
+export default doLimit(someLimit, 1);
diff --git a/lib/sortBy.js b/lib/sortBy.js
index 4f14823..8b78221 100644
--- a/lib/sortBy.js
+++ b/lib/sortBy.js
@@ -5,9 +5,9 @@ import property from 'lodash/_baseProperty';
import map from './map';
-export default function sortBy (arr, iterator, cb) {
+export default function sortBy (arr, iteratee, cb) {
map(arr, function (x, cb) {
- iterator(x, function (err, criteria) {
+ iteratee(x, function (err, criteria) {
if (err) return cb(err);
cb(null, {value: x, criteria: criteria});
});
diff --git a/lib/timeout.js b/lib/timeout.js
new file mode 100644
index 0000000..6af4f52
--- /dev/null
+++ b/lib/timeout.js
@@ -0,0 +1,29 @@
+'use strict';
+
+import initialParams from './internal/initialParams';
+
+export default function timeout(asyncFn, miliseconds) {
+ var originalCallback, timer;
+ var timedOut = false;
+
+ function injectedCallback() {
+ if (!timedOut) {
+ originalCallback.apply(null, arguments);
+ clearTimeout(timer);
+ }
+ }
+
+ function timeoutCallback() {
+ var error = new Error('Callback function timed out.');
+ error.code = 'ETIMEDOUT';
+ timedOut = true;
+ originalCallback(error);
+ }
+
+ return initialParams(function (args, origCallback) {
+ originalCallback = origCallback;
+ // setup timer and call original function
+ timer = setTimeout(timeoutCallback, miliseconds);
+ asyncFn.apply(null, args.concat(injectedCallback));
+ });
+}
diff --git a/lib/timesLimit.js b/lib/timesLimit.js
index 1ea7313..dbd9664 100644
--- a/lib/timesLimit.js
+++ b/lib/timesLimit.js
@@ -3,6 +3,6 @@
import mapLimit from './mapLimit';
import range from 'lodash/_baseRange';
-export default function timeLimit(count, limit, iterator, cb) {
- return mapLimit(range(0, count, 1), limit, iterator, cb);
+export default function timeLimit(count, limit, iteratee, cb) {
+ return mapLimit(range(0, count, 1), limit, iteratee, cb);
}
diff --git a/lib/transform.js b/lib/transform.js
index 3dddae8..819cd5d 100644
--- a/lib/transform.js
+++ b/lib/transform.js
@@ -4,15 +4,15 @@ import isArray from 'lodash/isArray';
import eachOf from './eachOf';
-export default function transform (arr, memo, iterator, callback) {
+export default function transform (arr, memo, iteratee, callback) {
if (arguments.length === 3) {
- callback = iterator;
- iterator = memo;
+ callback = iteratee;
+ iteratee = memo;
memo = isArray(arr) ? [] : {};
}
eachOf(arr, function(v, k, cb) {
- iterator(memo, v, k, cb);
+ iteratee(memo, v, k, cb);
}, function(err) {
callback(err, memo);
});
diff --git a/lib/until.js b/lib/until.js
index f9ed2fd..b1283f2 100644
--- a/lib/until.js
+++ b/lib/until.js
@@ -2,8 +2,8 @@
import whilst from './whilst';
-export default function until(test, iterator, cb) {
+export default function until(test, iteratee, cb) {
return whilst(function() {
return !test.apply(this, arguments);
- }, iterator, cb);
+ }, iteratee, cb);
}
diff --git a/lib/waterfall.js b/lib/waterfall.js
index 8867c87..aaed2ee 100644
--- a/lib/waterfall.js
+++ b/lib/waterfall.js
@@ -2,31 +2,34 @@
import isArray from 'lodash/isArray';
import noop from 'lodash/noop';
-import once from 'lodash/once';
+import once from './internal/once';
import rest from 'lodash/rest';
-import ensureAsync from './ensureAsync';
-import iterator from './iterator';
+import onlyOnce from './internal/onlyOnce';
export default function(tasks, cb) {
cb = once(cb || noop);
if (!isArray(tasks)) return cb(new Error('First argument to waterfall must be an array of functions'));
if (!tasks.length) return cb();
+ var taskIndex = 0;
- function wrapIterator(iterator) {
- return rest(function(err, args) {
+ function nextTask(args) {
+ if (taskIndex === tasks.length) {
+ return cb.apply(null, [null].concat(args));
+ }
+
+ var taskCallback = onlyOnce(rest(function(err, args) {
if (err) {
- cb.apply(null, [err].concat(args));
- } else {
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- } else {
- args.push(cb);
- }
- ensureAsync(iterator).apply(null, args);
+ return cb.apply(null, [err].concat(args));
}
- });
+ nextTask(args);
+ }));
+
+ args.push(taskCallback);
+
+ var task = tasks[taskIndex++];
+ task.apply(null, args);
}
- wrapIterator(iterator(tasks))();
+
+ nextTask([]);
}
diff --git a/lib/whilst.js b/lib/whilst.js
index feaec00..9406cd4 100644
--- a/lib/whilst.js
+++ b/lib/whilst.js
@@ -3,13 +3,13 @@
import noop from 'lodash/noop';
import rest from 'lodash/rest';
-export default function whilst(test, iterator, cb) {
+export default function whilst(test, iteratee, cb) {
cb = cb || noop;
if (!test()) return cb(null);
var next = rest(function(err, args) {
if (err) return cb(err);
- if (test.apply(this, args)) return iterator(next);
+ if (test.apply(this, args)) return iteratee(next);
cb.apply(null, [null].concat(args));
});
- iterator(next);
+ iteratee(next);
}
diff --git a/mocha_test/auto.js b/mocha_test/auto.js
index c6b7150..fb779ee 100644
--- a/mocha_test/auto.js
+++ b/mocha_test/auto.js
@@ -4,7 +4,7 @@ var _ = require('lodash');
describe('auto', function () {
- it('auto', function(done){
+ it('basics', function(done){
var callOrder = [];
async.auto({
task1: ['task2', function(results, callback){
@@ -40,7 +40,7 @@ describe('auto', function () {
},
function(err){
expect(err).to.equal(null);
- expect(callOrder).to.eql(['task2','task6','task3','task5','task1','task4']);
+ expect(callOrder).to.eql(['task2','task3','task6','task5','task1','task4']);
done();
});
});
@@ -204,7 +204,7 @@ describe('auto', function () {
// Issue 24 on github: https://github.com/caolan/async/issues#issue/24
// Issue 76 on github: https://github.com/caolan/async/issues#issue/76
- it('auto removeListener has side effect on loop iterator', function(done) {
+ it('auto removeListener has side effect on loop iteratee', function(done) {
async.auto({
task1: ['task3', function(/*callback*/) { done(); }],
task2: ['task3', function(/*callback*/) { /* by design: DON'T call callback */ }],
@@ -214,19 +214,8 @@ describe('auto', function () {
// Issue 410 on github: https://github.com/caolan/async/issues/410
it('auto calls callback multiple times', function(done) {
- if (process.browser) {
- // node only test
- return done();
- }
var finalCallCount = 0;
- var domain = require('domain').create();
- domain.on('error', function (e) {
- // ignore test error
- if (!e._test_error) {
- return done(e);
- }
- });
- domain.run(function () {
+ try {
async.auto({
task1: function(callback) { callback(null); },
task2: ['task1', function(results, callback) { callback(null); }]
@@ -239,7 +228,11 @@ describe('auto', function () {
e._test_error = true;
throw e;
});
- });
+ } catch (e) {
+ if (!e._test_error) {
+ throw e;
+ }
+ }
setTimeout(function () {
expect(finalCallCount).to.equal(1);
done();
@@ -293,7 +286,7 @@ describe('auto', function () {
callback(null, 'task1');
}]
});
- }).to.throw;
+ }).to.throw();
done();
});
@@ -308,7 +301,7 @@ describe('auto', function () {
callback(null, 'task2');
}]
});
- }).to.throw;
+ }).to.throw();
done();
});
@@ -344,4 +337,32 @@ describe('auto', function () {
});
});
+ it("does not allow calling callbacks twice", function () {
+ expect(function () {
+ async.auto({
+ bad: function (cb) {
+ cb();
+ cb();
+ }
+ }, function () {});
+
+ }).to.throw();
+ });
+
+ it("should avoid unncecessary deferrals", function (done) {
+ var isSync = true;
+
+ async.auto({
+ step1: function (cb) { cb(null, 1); },
+ step2: ["step1", function (results, cb) {
+ cb();
+ }]
+ }, function () {
+ expect(isSync).to.equal(true);
+ done();
+ });
+
+ isSync = false;
+ });
+
});
diff --git a/mocha_test/autoInject.js b/mocha_test/autoInject.js
new file mode 100644
index 0000000..059c7ae
--- /dev/null
+++ b/mocha_test/autoInject.js
@@ -0,0 +1,77 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+var _ = require('lodash');
+
+describe('autoInject', function () {
+
+ it("basics", function (done) {
+ var callOrder = [];
+ async.autoInject({
+ task1: function(task2, callback){
+ expect(task2).to.equal(2);
+ setTimeout(function(){
+ callOrder.push('task1');
+ callback(null, 1);
+ }, 25);
+ },
+ task2: function(callback){
+ setTimeout(function(){
+ callOrder.push('task2');
+ callback(null, 2);
+ }, 50);
+ },
+ task3: function(task2, callback){
+ expect(task2).to.equal(2);
+ callOrder.push('task3');
+ callback(null, 3);
+ },
+ task4: function(task1, task2, callback){
+ expect(task1).to.equal(1);
+ expect(task2).to.equal(2);
+ callOrder.push('task4');
+ callback(null, 4);
+ },
+ task5: function(task2, callback){
+ expect(task2).to.equal(2);
+ setTimeout(function(){
+ callOrder.push('task5');
+ callback(null, 5);
+ }, 0);
+ },
+ task6: function(task2, callback){
+ expect(task2).to.equal(2);
+ callOrder.push('task6');
+ callback(null, 6);
+ }
+ },
+ function(err, results){
+ expect(results.task6).to.equal(6);
+ expect(callOrder).to.eql(['task2','task3','task6','task5','task1','task4']);
+ done();
+ });
+ });
+
+ it('should work with array tasks', function (done) {
+ var callOrder = [];
+
+ async.autoInject({
+ task1: function (cb) {
+ callOrder.push('task1');
+ cb(null, 1);
+ },
+ task2: ['task3', function (task3, cb) {
+ expect(task3).to.equal(3);
+ callOrder.push('task2');
+ cb(null, 2);
+ }],
+ task3: function (cb) {
+ callOrder.push('task3');
+ cb(null, 3);
+ }
+ }, function () {
+ expect(callOrder).to.eql(['task1','task3','task2']);
+ done();
+ });
+ });
+
+});
diff --git a/mocha_test/cargo.js b/mocha_test/cargo.js
new file mode 100644
index 0000000..235b9a2
--- /dev/null
+++ b/mocha_test/cargo.js
@@ -0,0 +1,264 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+var assert = require('assert');
+
+describe('cargo', function () {
+
+ it('cargo', function (done) {
+ var call_order = [],
+ delays = [40, 40, 20];
+
+ // worker: --12--34--5-
+ // order of completion: 1,2,3,4,5
+
+ var c = async.cargo(function (tasks, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + tasks.join(' '));
+ callback('error', 'arg');
+ }, delays.shift());
+ }, 2);
+
+ c.push(1, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(c.length()).to.equal(3);
+ call_order.push('callback ' + 1);
+ });
+ c.push(2, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(c.length()).to.equal(3);
+ call_order.push('callback ' + 2);
+ });
+
+ expect(c.length()).to.equal(2);
+
+ // async push
+ setTimeout(function () {
+ c.push(3, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(c.length()).to.equal(1);
+ call_order.push('callback ' + 3);
+ });
+ }, 15);
+ setTimeout(function () {
+ c.push(4, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(c.length()).to.equal(1);
+ call_order.push('callback ' + 4);
+ });
+ expect(c.length()).to.equal(2);
+ c.push(5, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(c.length()).to.equal(0);
+ call_order.push('callback ' + 5);
+ });
+ }, 30);
+
+
+ c.drain = function () {
+ expect(call_order).to.eql([
+ 'process 1 2', 'callback 1', 'callback 2',
+ 'process 3 4', 'callback 3', 'callback 4',
+ 'process 5' , 'callback 5'
+ ]);
+ expect(c.length()).to.equal(0);
+ done();
+ };
+ });
+
+ it('without callback', function (done) {
+ var call_order = [],
+ delays = [40,20,60,20];
+
+ // worker: --1-2---34-5-
+ // order of completion: 1,2,3,4,5
+
+ var c = async.cargo(function (tasks, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + tasks.join(' '));
+ callback('error', 'arg');
+ }, delays.shift());
+ }, 2);
+
+ c.push(1);
+
+ setTimeout(function () {
+ c.push(2);
+ }, 30);
+ setTimeout(function () {
+ c.push(3);
+ c.push(4);
+ c.push(5);
+ }, 50);
+
+ setTimeout(function () {
+ expect(call_order).to.eql([
+ 'process 1',
+ 'process 2',
+ 'process 3 4',
+ 'process 5'
+ ]);
+ done();
+ }, 200);
+ });
+
+ it('bulk task', function (done) {
+ var call_order = [],
+ delays = [30,20];
+
+ // worker: -123-4-
+ // order of completion: 1,2,3,4
+
+ var c = async.cargo(function (tasks, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + tasks.join(' '));
+ callback('error', tasks.join(' '));
+ }, delays.shift());
+ }, 3);
+
+ c.push( [1,2,3,4], function (err, arg) {
+ expect(err).to.equal('error');
+ call_order.push('callback ' + arg);
+ });
+
+ expect(c.length()).to.equal(4);
+
+ setTimeout(function () {
+ expect(call_order).to.eql([
+ 'process 1 2 3', 'callback 1 2 3',
+ 'callback 1 2 3', 'callback 1 2 3',
+ 'process 4', 'callback 4',
+ ]);
+ expect(c.length()).to.equal(0);
+ done();
+ }, 200);
+ });
+
+ it('drain once', function (done) {
+
+ var c = async.cargo(function (tasks, callback) {
+ callback();
+ }, 3);
+
+ var drainCounter = 0;
+ c.drain = function () {
+ drainCounter++;
+ };
+
+ for(var i = 0; i < 10; i++){
+ c.push(i);
+ }
+
+ setTimeout(function(){
+ expect(drainCounter).to.equal(1);
+ done();
+ }, 50);
+ });
+
+ it('drain twice', function (done) {
+
+ var c = async.cargo(function (tasks, callback) {
+ callback();
+ }, 3);
+
+ function loadCargo(){
+ for(var i = 0; i < 10; i++){
+ c.push(i);
+ }
+ }
+
+ var drainCounter = 0;
+ c.drain = function () {
+ drainCounter++;
+ };
+
+ loadCargo();
+ setTimeout(loadCargo, 50);
+
+ setTimeout(function(){
+ expect(drainCounter).to.equal(2);
+ done();
+ }, 100);
+ });
+
+ it('events', function (done) {
+ var calls = [];
+ var q = async.cargo(function(task, cb) {
+ // nop
+ calls.push('process ' + task);
+ async.setImmediate(cb);
+ }, 1);
+ q.concurrency = 3;
+
+ q.saturated = function() {
+ assert(q.running() == 3, 'cargo should be saturated now');
+ calls.push('saturated');
+ };
+ q.empty = function() {
+ assert(q.length() === 0, 'cargo should be empty now');
+ calls.push('empty');
+ };
+ q.drain = function() {
+ assert(
+ q.length() === 0 && q.running() === 0,
+ 'cargo should be empty now and no more workers should be running'
+ );
+ calls.push('drain');
+ expect(calls).to.eql([
+ 'process foo',
+ 'process bar',
+ 'saturated',
+ 'process zoo',
+ 'foo cb',
+ 'saturated',
+ 'process poo',
+ 'bar cb',
+ 'empty',
+ 'saturated',
+ 'process moo',
+ 'zoo cb',
+ 'poo cb',
+ 'moo cb',
+ 'drain'
+ ]);
+ done();
+ };
+ q.push('foo', function () {calls.push('foo cb');});
+ q.push('bar', function () {calls.push('bar cb');});
+ q.push('zoo', function () {calls.push('zoo cb');});
+ q.push('poo', function () {calls.push('poo cb');});
+ q.push('moo', function () {calls.push('moo cb');});
+ });
+
+ it('expose payload', function (done) {
+ var called_once = false;
+ var cargo= async.cargo(function(tasks, cb) {
+ if (!called_once) {
+ expect(cargo.payload).to.equal(1);
+ assert(tasks.length === 1, 'should start with payload = 1');
+ } else {
+ expect(cargo.payload).to.equal(2);
+ assert(tasks.length === 2, 'next call shold have payload = 2');
+ }
+ called_once = true;
+ setTimeout(cb, 25);
+ }, 1);
+
+ cargo.drain = function () {
+ done();
+ };
+
+ expect(cargo.payload).to.equal(1);
+
+ cargo.push([1, 2, 3]);
+
+ setTimeout(function () {
+ cargo.payload = 2;
+ }, 15);
+ });
+
+});
diff --git a/mocha_test/constant.js b/mocha_test/constant.js
new file mode 100644
index 0000000..d76076c
--- /dev/null
+++ b/mocha_test/constant.js
@@ -0,0 +1,28 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+
+describe('constant', function () {
+
+ it('basic usage', function(done){
+ var f = async.constant(42, 1, 2, 3);
+ f(function (err, value, a, b, c) {
+ expect(err).to.equal(null);
+ expect(value).to.equal(42);
+ expect(a).to.equal(1);
+ expect(b).to.equal(2);
+ expect(c).to.equal(3);
+ done();
+ });
+ });
+
+ it('called with multiple arguments', function(done){
+ var f = async.constant(42, 1, 2, 3);
+ f('argument to ignore', 'another argument', function (err, value, a) {
+ expect(err).to.equal(null);
+ expect(value).to.equal(42);
+ expect(a).to.equal(1);
+ done();
+ });
+ });
+
+});
diff --git a/mocha_test/detect.js b/mocha_test/detect.js
index e1eec79..ddc86ce 100644
--- a/mocha_test/detect.js
+++ b/mocha_test/detect.js
@@ -3,16 +3,16 @@ var expect = require('chai').expect;
describe("detect", function () {
- function detectIterator(call_order, x, callback) {
+ function detectIteratee(call_order, x, callback) {
setTimeout(function(){
call_order.push(x);
callback(null, x == 2);
- }, x*25);
+ }, x*5);
}
it('detect', function(done){
var call_order = [];
- async.detect([3,2,1], detectIterator.bind(this, call_order), function(err, result){
+ async.detect([3,2,1], detectIteratee.bind(this, call_order), function(err, result){
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -20,12 +20,12 @@ describe("detect", function () {
setTimeout(function(){
expect(call_order).to.eql([1,2,'callback',3]);
done();
- }, 100);
+ }, 25);
});
it('detect - mulitple matches', function(done){
var call_order = [];
- async.detect([3,2,2,1,2], detectIterator.bind(this, call_order), function(err, result){
+ async.detect([3,2,2,1,2], detectIteratee.bind(this, call_order), function(err, result){
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -33,7 +33,7 @@ describe("detect", function () {
setTimeout(function(){
expect(call_order).to.eql([1,2,'callback',2,2,3]);
done();
- }, 100);
+ }, 25);
});
it('detect error', function(done){
@@ -48,7 +48,7 @@ describe("detect", function () {
it('detectSeries', function(done){
var call_order = [];
- async.detectSeries([3,2,1], detectIterator.bind(this, call_order), function(err, result){
+ async.detectSeries([3,2,1], detectIteratee.bind(this, call_order), function(err, result){
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -56,12 +56,12 @@ describe("detect", function () {
setTimeout(function(){
expect(call_order).to.eql([3,2,'callback']);
done();
- }, 200);
+ }, 50);
});
it('detectSeries - multiple matches', function(done){
var call_order = [];
- async.detectSeries([3,2,2,1,2], detectIterator.bind(this, call_order), function(err, result){
+ async.detectSeries([3,2,2,1,2], detectIteratee.bind(this, call_order), function(err, result){
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -69,7 +69,21 @@ describe("detect", function () {
setTimeout(function(){
expect(call_order).to.eql([3,2,'callback']);
done();
- }, 200);
+ }, 50);
+ });
+
+ it('detect no callback', function(done) {
+ var calls = [];
+
+ async.detect([1, 2, 3], function (val, cb) {
+ calls.push(val);
+ cb();
+ });
+
+ setTimeout(function () {
+ expect(calls).to.eql([1, 2, 3]);
+ done();
+ }, 10);
});
it('detectSeries - ensure stop', function (done) {
@@ -85,7 +99,7 @@ describe("detect", function () {
it('detectLimit', function(done){
var call_order = [];
- async.detectLimit([3, 2, 1], 2, detectIterator.bind(this, call_order), function(err, result) {
+ async.detectLimit([3, 2, 1], 2, detectIteratee.bind(this, call_order), function(err, result) {
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -93,12 +107,12 @@ describe("detect", function () {
setTimeout(function() {
expect(call_order).to.eql([2, 'callback', 3]);
done();
- }, 100);
+ }, 25);
});
it('detectLimit - multiple matches', function(done){
var call_order = [];
- async.detectLimit([3,2,2,1,2], 2, detectIterator.bind(this, call_order), function(err, result){
+ async.detectLimit([3,2,2,1,2], 2, detectIteratee.bind(this, call_order), function(err, result){
call_order.push('callback');
expect(err).to.equal(null);
expect(result).to.equal(2);
@@ -106,7 +120,7 @@ describe("detect", function () {
setTimeout(function(){
expect(call_order).to.eql([2, 'callback', 3]);
done();
- }, 100);
+ }, 25);
});
it('detectLimit - ensure stop', function (done) {
@@ -120,4 +134,18 @@ describe("detect", function () {
});
});
+
+ it('find alias', function(){
+ expect(async.find).to.equal(async.detect);
+ });
+
+ it('findLimit alias', function(){
+ expect(async.findLimit).to.equal(async.detectLimit);
+ });
+
+ it('findSeries alias', function(){
+ expect(async.findSeries).to.be.a('function');
+ expect(async.findSeries).to.equal(async.detectSeries);
+ });
+
});
diff --git a/mocha_test/every.js b/mocha_test/every.js
index 2f562ce..ed4693e 100644
--- a/mocha_test/every.js
+++ b/mocha_test/every.js
@@ -63,14 +63,14 @@ describe("every", function () {
setTimeout(function(){
call_order.push(x);
callback(null, x === 1);
- }, x*25);
+ }, x*5);
}, function(){
call_order.push('callback');
});
setTimeout(function(){
expect(call_order).to.eql([1,2,'callback',3]);
done();
- }, 100);
+ }, 25);
});
it('error', function(done){
@@ -87,4 +87,13 @@ describe("every", function () {
expect(async.all).to.equal(async.every);
});
+ it('allLimit alias', function(){
+ expect(async.allLimit).to.equal(async.everyLimit);
+ });
+
+ it('allSeries alias', function(){
+ expect(async.allSeries).to.be.a('function');
+ expect(async.allSeries).to.equal(async.everySeries);
+ });
+
});
diff --git a/mocha_test/filter.js b/mocha_test/filter.js
index 58f9a0b..8b4b268 100644
--- a/mocha_test/filter.js
+++ b/mocha_test/filter.js
@@ -1,10 +1,10 @@
var async = require('../lib');
var expect = require('chai').expect;
-function filterIterator(x, callback) {
+function filterIteratee(x, callback) {
setTimeout(function(){
callback(null, x % 2);
- }, x*25);
+ }, x*5);
}
function testLimit(arr, limitFunc, limit, iter, done) {
@@ -22,7 +22,7 @@ function testLimit(arr, limitFunc, limit, iter, done) {
describe("filter", function () {
it('filter', function(done){
- async.filter([3,1,2], filterIterator, function(err, results){
+ async.filter([3,1,2], filterIteratee, function(err, results){
expect(err).to.equal(null);
expect(results).to.eql([3,1]);
done();
@@ -52,7 +52,7 @@ describe("filter", function () {
});
it('filterSeries', function(done){
- async.filterSeries([3,1,2], filterIterator, function(err, results){
+ async.filterSeries([3,1,2], filterIteratee, function(err, results){
expect(err).to.equal(null);
expect(results).to.eql([3,1]);
done();
@@ -82,7 +82,7 @@ describe("filter", function () {
describe("reject", function () {
it('reject', function(done){
- async.reject([3,1,2], filterIterator, function(err, results){
+ async.reject([3,1,2], filterIteratee, function(err, results){
expect(err).to.equal(null);
expect(results).to.eql([2]);
done();
@@ -112,7 +112,7 @@ describe("reject", function () {
});
it('rejectSeries', function(done){
- async.rejectSeries([3,1,2], filterIterator, function(err, results){
+ async.rejectSeries([3,1,2], filterIteratee, function(err, results){
expect(err).to.equal(null);
expect(results).to.eql([2]);
done();
diff --git a/mocha_test/nextTick.js b/mocha_test/nextTick.js
new file mode 100644
index 0000000..b428822
--- /dev/null
+++ b/mocha_test/nextTick.js
@@ -0,0 +1,38 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+
+describe("nextTick", function () {
+
+ it('basics', function(done){
+ var call_order = [];
+ async.nextTick(function(){call_order.push('two');});
+ call_order.push('one');
+ setTimeout(function(){
+ expect(call_order).to.eql(['one','two']);
+ done();
+ }, 50);
+ });
+
+ it('nextTick in the browser', function(done){
+ if (!process.browser) {
+ // skip this test in node
+ return done();
+ }
+
+ var call_order = [];
+ async.nextTick(function(){call_order.push('two');});
+
+ call_order.push('one');
+ setTimeout(function(){
+ expect(call_order).to.eql(['one','two']);
+ done();
+ }, 50);
+ });
+
+ it("extra args", function (done) {
+ async.nextTick(function (a, b, c) {
+ expect([a, b, c]).to.eql([1, 2, 3]);
+ done();
+ }, 1, 2, 3);
+ });
+});
diff --git a/mocha_test/priorityQueue.js b/mocha_test/priorityQueue.js
index 9832b43..fa5cfce 100644
--- a/mocha_test/priorityQueue.js
+++ b/mocha_test/priorityQueue.js
@@ -2,6 +2,114 @@ var async = require('../lib');
var expect = require('chai').expect;
describe('priorityQueue', function() {
+
+ it('priorityQueue', function (done) {
+ var call_order = [];
+
+ // order of completion: 2,1,4,3
+
+ var q = async.priorityQueue(function (task, callback) {
+ call_order.push('process ' + task);
+ callback('error', 'arg');
+ }, 1);
+
+ q.push(1, 1.4, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(2);
+ call_order.push('callback ' + 1);
+ });
+ q.push(2, 0.2, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(3);
+ call_order.push('callback ' + 2);
+ });
+ q.push(3, 3.8, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 3);
+ });
+ q.push(4, 2.9, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(1);
+ call_order.push('callback ' + 4);
+ });
+ expect(q.length()).to.equal(4);
+ expect(q.concurrency).to.equal(1);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 2', 'callback 2',
+ 'process 1', 'callback 1',
+ 'process 4', 'callback 4',
+ 'process 3', 'callback 3'
+ ]);
+ expect(q.concurrency).to.equal(1);
+ expect(q.length()).to.equal(0);
+ done();
+ };
+ });
+
+ it('concurrency', function (done) {
+ var call_order = [],
+ delays = [160,80,240,80];
+
+ // worker1: --2-3
+ // worker2: -1---4
+ // order of completion: 1,2,3,4
+
+ var q = async.priorityQueue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ callback('error', 'arg');
+ }, delays.splice(0,1)[0]);
+ }, 2);
+
+ q.push(1, 1.4, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(2);
+ call_order.push('callback ' + 1);
+ });
+ q.push(2, 0.2, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(1);
+ call_order.push('callback ' + 2);
+ });
+ q.push(3, 3.8, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 3);
+ });
+ q.push(4, 2.9, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 4);
+ });
+ expect(q.length()).to.equal(4);
+ expect(q.concurrency).to.equal(2);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 1', 'callback 1',
+ 'process 2', 'callback 2',
+ 'process 3', 'callback 3',
+ 'process 4', 'callback 4'
+ ]);
+ expect(q.concurrency).to.equal(2);
+ expect(q.length()).to.equal(0);
+ done();
+ };
+ });
+
+
+
context('q.unsaturated(): ',function() {
it('should have a default buffer property that equals 25% of the concurrenct rate', function(done) {
var calls = [];
@@ -31,8 +139,8 @@ describe('priorityQueue', function() {
var calls = [];
var q = async.priorityQueue(function(task, cb) {
calls.push('process ' + task);
- async.setImmediate(cb);
- }, 10);
+ setTimeout(cb, 10);
+ }, 4);
q.unsaturated = function() {
calls.push('unsaturated');
};
@@ -43,18 +151,21 @@ describe('priorityQueue', function() {
'unsaturated',
'unsaturated',
'unsaturated',
- 'unsaturated',
- 'unsaturated',
'process foo4',
'process foo3',
'process foo2',
'process foo1',
- 'process foo0',
'foo4 cb',
+ 'unsaturated',
+ 'process foo0',
'foo3 cb',
+ 'unsaturated',
'foo2 cb',
+ 'unsaturated',
'foo1 cb',
- 'foo0 cb'
+ 'unsaturated',
+ 'foo0 cb',
+ 'unsaturated'
]);
done();
}, 50);
diff --git a/mocha_test/queue.js b/mocha_test/queue.js
index f64eef5..2baf124 100644
--- a/mocha_test/queue.js
+++ b/mocha_test/queue.js
@@ -1,8 +1,606 @@
var async = require('../lib');
var expect = require('chai').expect;
+var assert = require('assert');
describe('queue', function(){
+
+ it('basics', function(done) {
+
+ var call_order = [];
+ var delays = [40,20,60,20];
+
+
+ // worker1: --1-4
+ // worker2: -2---3
+ // order of completion: 2,1,4,3
+
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ callback('error', 'arg');
+ }, delays.shift());
+ }, 2);
+
+ q.push(1, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(1);
+ call_order.push('callback ' + 1);
+ });
+ q.push(2, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(2);
+ call_order.push('callback ' + 2);
+ });
+ q.push(3, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 3);
+ });
+ q.push(4, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 4);
+ });
+ expect(q.length()).to.equal(4);
+ expect(q.concurrency).to.equal(2);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 2', 'callback 2',
+ 'process 1', 'callback 1',
+ 'process 4', 'callback 4',
+ 'process 3', 'callback 3'
+ ]);
+ expect(q.concurrency).to.equal(2);
+ expect(q.length()).to.equal(0);
+ done();
+ };
+ });
+
+ it('default concurrency', function(done) {
+ var call_order = [],
+ delays = [40,20,60,20];
+
+ // order of completion: 1,2,3,4
+
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ callback('error', 'arg');
+ }, delays.shift());
+ });
+
+ q.push(1, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(3);
+ call_order.push('callback ' + 1);
+ });
+ q.push(2, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(2);
+ call_order.push('callback ' + 2);
+ });
+ q.push(3, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(1);
+ call_order.push('callback ' + 3);
+ });
+ q.push(4, function (err, arg) {
+ expect(err).to.equal('error');
+ expect(arg).to.equal('arg');
+ expect(q.length()).to.equal(0);
+ call_order.push('callback ' + 4);
+ });
+ expect(q.length()).to.equal(4);
+ expect(q.concurrency).to.equal(1);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 1', 'callback 1',
+ 'process 2', 'callback 2',
+ 'process 3', 'callback 3',
+ 'process 4', 'callback 4'
+ ]);
+ expect(q.concurrency).to.equal(1);
+ expect(q.length()).to.equal(0);
+ done();
+ };
+ });
+
+ it('zero concurrency', function(done){
+ expect(function () {
+ async.queue(function (task, callback) {
+ callback(null, task);
+ }, 0);
+ }).to.throw();
+ done();
+ });
+
+ it('error propagation', function(done){
+ var results = [];
+
+ var q = async.queue(function (task, callback) {
+ callback(task.name === 'foo' ? new Error('fooError') : null);
+ }, 2);
+
+ q.drain = function() {
+ expect(results).to.eql(['bar', 'fooError']);
+ done();
+ };
+
+ q.push({name: 'bar'}, function (err) {
+ if(err) {
+ results.push('barError');
+ return;
+ }
+
+ results.push('bar');
+ });
+
+ q.push({name: 'foo'}, function (err) {
+ if(err) {
+ results.push('fooError');
+ return;
+ }
+
+ results.push('foo');
+ });
+ });
+
+ // The original queue implementation allowed the concurrency to be changed only
+ // on the same event loop during which a task was added to the queue. This
+ // test attempts to be a more robust test.
+ // Start with a concurrency of 1. Wait until a leter event loop and change
+ // the concurrency to 2. Wait again for a later loop then verify the concurrency
+ // Repeat that one more time by chaning the concurrency to 5.
+ it('changing concurrency', function(done) {
+
+ var q = async.queue(function(task, callback){
+ setTimeout(function(){
+ callback();
+ }, 10);
+ }, 1);
+
+ for(var i = 0; i < 50; i++){
+ q.push('');
+ }
+
+ q.drain = function(){
+ done();
+ };
+
+ setTimeout(function(){
+ expect(q.concurrency).to.equal(1);
+ q.concurrency = 2;
+ setTimeout(function(){
+ expect(q.running()).to.equal(2);
+ q.concurrency = 5;
+ setTimeout(function(){
+ expect(q.running()).to.equal(5);
+ }, 40);
+ }, 40);
+ }, 40);
+ });
+
+ it('push without callback', function(done) {
+ var call_order = [],
+ delays = [40,20,60,20];
+
+ // worker1: --1-4
+ // worker2: -2---3
+ // order of completion: 2,1,4,3
+
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ callback('error', 'arg');
+ }, delays.shift());
+ }, 2);
+
+ q.push(1);
+ q.push(2);
+ q.push(3);
+ q.push(4);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 2',
+ 'process 1',
+ 'process 4',
+ 'process 3'
+ ]);
+ done();
+ };
+ });
+
+ it('push with non-function', function(done) {
+ var q = async.queue(function () {}, 1);
+ expect(function () {
+ q.push({}, 1);
+ }).to.throw();
+ done();
+ });
+
+ it('unshift', function(done) {
+ var queue_order = [];
+
+ var q = async.queue(function (task, callback) {
+ queue_order.push(task);
+ callback();
+ }, 1);
+
+ q.unshift(4);
+ q.unshift(3);
+ q.unshift(2);
+ q.unshift(1);
+
+ setTimeout(function () {
+ expect(queue_order).to.eql([ 1, 2, 3, 4 ]);
+ done();
+ }, 100);
+ });
+
+ it('too many callbacks', function(done) {
+ var q = async.queue(function (task, callback) {
+ callback();
+ expect(function() {
+ callback();
+ }).to.throw();
+ done();
+ }, 2);
+
+ q.push(1);
+ });
+
+ it('bulk task', function(done) {
+ var call_order = [],
+ delays = [40,20,60,20];
+
+ // worker1: --1-4
+ // worker2: -2---3
+ // order of completion: 2,1,4,3
+
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ callback('error', task);
+ }, delays.splice(0,1)[0]);
+ }, 2);
+
+ q.push( [1,2,3,4], function (err, arg) {
+ expect(err).to.equal('error');
+ call_order.push('callback ' + arg);
+ });
+
+ expect(q.length()).to.equal(4);
+ expect(q.concurrency).to.equal(2);
+
+ q.drain = function () {
+ expect(call_order).to.eql([
+ 'process 2', 'callback 2',
+ 'process 1', 'callback 1',
+ 'process 4', 'callback 4',
+ 'process 3', 'callback 3'
+ ]);
+ expect(q.concurrency).to.equal(2);
+ expect(q.length()).to.equal(0);
+ done();
+ };
+ });
+
+ it('idle', function(done) {
+ var q = async.queue(function (task, callback) {
+ // Queue is busy when workers are running
+ expect(q.idle()).to.equal(false);
+ callback();
+ }, 1);
+
+ // Queue is idle before anything added
+ expect(q.idle()).to.equal(true);
+
+ q.unshift(4);
+ q.unshift(3);
+ q.unshift(2);
+ q.unshift(1);
+
+ // Queue is busy when tasks added
+ expect(q.idle()).to.equal(false);
+
+ q.drain = function() {
+ // Queue is idle after drain
+ expect(q.idle()).to.equal(true);
+ done();
+ };
+ });
+
+ it('pause', function(done) {
+ var call_order = [],
+ task_timeout = 40,
+ pause_timeout = 100,
+ resume_timeout = 180,
+ tasks = [ 1, 2, 3, 4, 5, 6 ],
+
+ elapsed = (function () {
+ var start = (new Date()).valueOf();
+ return function () {
+ return Math.round(((new Date()).valueOf() - start) / 40) * 40;
+ };
+ })();
+
+ var q = async.queue(function (task, callback) {
+ call_order.push('process ' + task);
+ call_order.push('timeout ' + elapsed());
+ callback();
+ });
+
+ function pushTask () {
+ var task = tasks.shift();
+ if (!task) { return; }
+ setTimeout(function () {
+ q.push(task);
+ pushTask();
+ }, task_timeout);
+ }
+ pushTask();
+
+ setTimeout(function () {
+ q.pause();
+ expect(q.paused).to.equal(true);
+ }, pause_timeout);
+
+ setTimeout(function () {
+ q.resume();
+ expect(q.paused).to.equal(false);
+ }, resume_timeout);
+
+ setTimeout(function () {
+ expect(call_order).to.eql([
+ 'process 1', 'timeout 40',
+ 'process 2', 'timeout 80',
+ 'process 3', 'timeout 200',
+ 'process 4', 'timeout 200',
+ 'process 5', 'timeout 200',
+ 'process 6', 'timeout 240'
+ ]);
+ done();
+ }, 300);
+ });
+
+ it('pause in worker with concurrency', function(done) {
+ var call_order = [];
+ var q = async.queue(function (task, callback) {
+ if (task.isLongRunning) {
+ q.pause();
+ setTimeout(function () {
+ call_order.push(task.id);
+ q.resume();
+ callback();
+ }, 50);
+ }
+ else {
+ call_order.push(task.id);
+ setTimeout(callback, 10);
+ }
+ }, 10);
+
+ q.push({ id: 1, isLongRunning: true});
+ q.push({ id: 2 });
+ q.push({ id: 3 });
+ q.push({ id: 4 });
+ q.push({ id: 5 });
+
+ q.drain = function () {
+ expect(call_order).to.eql([1, 2, 3, 4, 5]);
+ done();
+ };
+ });
+
+ it('pause with concurrency', function(done) {
+ var call_order = [],
+ task_timeout = 40,
+ pause_timeout = 20,
+ resume_timeout = 110,
+ tasks = [ 1, 2, 3, 4, 5, 6 ],
+
+ elapsed = (function () {
+ var start = (new Date()).valueOf();
+ return function () {
+ return Math.round(((new Date()).valueOf() - start) / 40) * 40;
+ };
+ })();
+
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ call_order.push('process ' + task);
+ call_order.push('timeout ' + elapsed());
+ callback();
+ }, task_timeout);
+ }, 2);
+
+ q.push(tasks);
+
+ setTimeout(function () {
+ q.pause();
+ expect(q.paused).to.equal(true);
+ }, pause_timeout);
+
+ setTimeout(function () {
+ q.resume();
+ expect(q.paused).to.equal(false);
+ }, resume_timeout);
+
+ setTimeout(function () {
+ expect(q.running()).to.equal(2);
+ }, resume_timeout + 10);
+
+ setTimeout(function () {
+ expect(call_order).to.eql([
+ 'process 1', 'timeout 40',
+ 'process 2', 'timeout 40',
+ 'process 3', 'timeout 160',
+ 'process 4', 'timeout 160',
+ 'process 5', 'timeout 200',
+ 'process 6', 'timeout 200'
+ ]);
+ done();
+ }, 300);
+ });
+
+ it('start paused', function(done) {
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ callback();
+ }, 40);
+ }, 2);
+ q.pause();
+
+ q.push([1, 2, 3]);
+
+ setTimeout(function () {
+ q.resume();
+ }, 5);
+
+ setTimeout(function () {
+ expect(q.tasks.length).to.equal(1);
+ expect(q.running()).to.equal(2);
+ q.resume();
+ }, 15);
+
+ q.drain = function () {
+ done();
+ };
+ });
+
+ it('kill', function(done) {
+ var q = async.queue(function (task, callback) {
+ setTimeout(function () {
+ throw new Error("Function should never be called");
+ }, 20);
+ }, 1);
+ q.drain = function() {
+ throw new Error("Function should never be called");
+ };
+
+ q.push(0);
+
+ q.kill();
+
+ setTimeout(function() {
+ expect(q.length()).to.equal(0);
+ done();
+ }, 40);
+ });
+
+ it('events', function(done) {
+ var calls = [];
+ var q = async.queue(function(task, cb) {
+ // nop
+ calls.push('process ' + task);
+ setTimeout(cb, 10);
+ }, 3);
+ q.concurrency = 3;
+
+ q.saturated = function() {
+ assert(q.running() == 3, 'queue should be saturated now');
+ calls.push('saturated');
+ };
+ q.empty = function() {
+ assert(q.length() === 0, 'queue should be empty now');
+ calls.push('empty');
+ };
+ q.drain = function() {
+ assert(
+ q.length() === 0 && q.running() === 0,
+ 'queue should be empty now and no more workers should be running'
+ );
+ calls.push('drain');
+ expect(calls).to.eql([
+ 'process foo',
+ 'process bar',
+ 'saturated',
+ 'process zoo',
+ 'foo cb',
+ 'saturated',
+ 'process poo',
+ 'bar cb',
+ 'empty',
+ 'saturated',
+ 'process moo',
+ 'zoo cb',
+ 'poo cb',
+ 'moo cb',
+ 'drain'
+ ]);
+ done();
+ };
+ q.push('foo', function () {calls.push('foo cb');});
+ q.push('bar', function () {calls.push('bar cb');});
+ q.push('zoo', function () {calls.push('zoo cb');});
+ q.push('poo', function () {calls.push('poo cb');});
+ q.push('moo', function () {calls.push('moo cb');});
+ });
+
+ it('empty', function(done) {
+ var calls = [];
+ var q = async.queue(function(task, cb) {
+ // nop
+ calls.push('process ' + task);
+ async.setImmediate(cb);
+ }, 3);
+
+ q.drain = function() {
+ assert(
+ q.length() === 0 && q.running() === 0,
+ 'queue should be empty now and no more workers should be running'
+ );
+ calls.push('drain');
+ expect(calls).to.eql([
+ 'drain'
+ ]);
+ done();
+ };
+ q.push([]);
+ });
+
+ it('saturated', function(done) {
+ var saturatedCalled = false;
+ var q = async.queue(function(task, cb) {
+ async.setImmediate(cb);
+ }, 2);
+
+ q.saturated = function () {
+ saturatedCalled = true;
+ };
+ q.drain = function () {
+ assert(saturatedCalled, "saturated not called");
+ done();
+ };
+
+ q.push(['foo', 'bar', 'baz', 'moo']);
+ });
+
+ it('started', function(done) {
+
+ var q = async.queue(function(task, cb) {
+ cb(null, task);
+ });
+
+ expect(q.started).to.equal(false);
+ q.push([]);
+ expect(q.started).to.equal(true);
+ done();
+ });
+
+
+
context('q.unsaturated(): ',function() {
it('should have a default buffer property that equals 25% of the concurrenct rate', function(done){
var calls = [];
@@ -31,7 +629,7 @@ describe('queue', function(){
var q = async.queue(function(task, cb) {
calls.push('process ' + task);
async.setImmediate(cb);
- }, 10);
+ }, 4);
q.unsaturated = function() {
calls.push('unsaturated');
};
@@ -39,21 +637,21 @@ describe('queue', function(){
expect(calls.indexOf('unsaturated')).to.be.above(-1);
setTimeout(function() {
expect(calls).eql([
- 'unsaturated',
- 'unsaturated',
- 'unsaturated',
- 'unsaturated',
- 'unsaturated',
'process foo0',
'process foo1',
'process foo2',
'process foo3',
- 'process foo4',
'foo0 cb',
+ 'unsaturated',
+ 'process foo4',
'foo1 cb',
+ 'unsaturated',
'foo2 cb',
+ 'unsaturated',
'foo3 cb',
- 'foo4 cb'
+ 'unsaturated',
+ 'foo4 cb',
+ 'unsaturated'
]);
done();
}, 50);
diff --git a/mocha_test/retry.js b/mocha_test/retry.js
new file mode 100644
index 0000000..2aa48e8
--- /dev/null
+++ b/mocha_test/retry.js
@@ -0,0 +1,101 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+var assert = require('assert');
+
+describe("retry", function () {
+
+ // Issue 306 on github: https://github.com/caolan/async/issues/306
+ it('retry when attempt succeeds',function(done) {
+ var failed = 3;
+ var callCount = 0;
+ var expectedResult = 'success';
+ function fn(callback) {
+ callCount++;
+ failed--;
+ if (!failed) callback(null, expectedResult);
+ else callback(true); // respond with error
+ }
+ async.retry(fn, function(err, result){
+ assert(err === null, err + " passed instead of 'null'");
+ assert.equal(callCount, 3, 'did not retry the correct number of times');
+ assert.equal(result, expectedResult, 'did not return the expected result');
+ done();
+ });
+ });
+
+ it('retry when all attempts succeeds',function(done) {
+ var times = 3;
+ var callCount = 0;
+ var error = 'ERROR';
+ var erroredResult = 'RESULT';
+ function fn(callback) {
+ callCount++;
+ callback(error + callCount, erroredResult + callCount); // respond with indexed values
+ }
+ async.retry(times, fn, function(err, result){
+ assert.equal(callCount, 3, "did not retry the correct number of times");
+ assert.equal(err, error + times, "Incorrect error was returned");
+ assert.equal(result, erroredResult + times, "Incorrect result was returned");
+ done();
+ });
+ });
+
+ it('retry fails with invalid arguments',function(done) {
+ expect(function() {
+ async.retry("");
+ }).to.throw();
+ expect(function() {
+ async.retry();
+ }).to.throw();
+ expect(function() {
+ async.retry(function() {}, 2, function() {});
+ }).to.throw();
+ done();
+ });
+
+ it('retry with interval when all attempts succeeds',function(done) {
+ var times = 3;
+ var interval = 50;
+ var callCount = 0;
+ var error = 'ERROR';
+ var erroredResult = 'RESULT';
+ function fn(callback) {
+ callCount++;
+ callback(error + callCount, erroredResult + callCount); // respond with indexed values
+ }
+ var start = new Date().getTime();
+ async.retry({ times: times, interval: interval}, fn, function(err, result){
+ var now = new Date().getTime();
+ var duration = now - start;
+ assert(duration >= (interval * (times -1)), 'did not include interval');
+ assert.equal(callCount, 3, "did not retry the correct number of times");
+ assert.equal(err, error + times, "Incorrect error was returned");
+ assert.equal(result, erroredResult + times, "Incorrect result was returned");
+ done();
+ });
+ });
+
+ it("should not require a callback", function (done) {
+ var called = false;
+ async.retry(3, function(cb) {
+ called = true;
+ cb();
+ });
+ setTimeout(function () {
+ assert(called);
+ done();
+ }, 10);
+ });
+
+ it("should not require a callback and use the default times", function (done) {
+ var calls = 0;
+ async.retry(function(cb) {
+ calls++;
+ cb("fail");
+ });
+ setTimeout(function () {
+ expect(calls).to.equal(5);
+ done();
+ }, 50);
+ });
+});
diff --git a/mocha_test/retryable.js b/mocha_test/retryable.js
new file mode 100644
index 0000000..7147269
--- /dev/null
+++ b/mocha_test/retryable.js
@@ -0,0 +1,66 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+var assert = require('assert');
+
+describe('retryable', function () {
+ it('basics', function (done) {
+ var calls = 0;
+ var retryableTask = async.retryable(3, function (arg, cb) {
+ calls++;
+ expect(arg).to.equal(42);
+ cb('fail');
+ });
+
+ retryableTask(42, function (err) {
+ expect(err).to.equal('fail');
+ expect(calls).to.equal(3);
+ done();
+ });
+
+ setTimeout(function () {
+ }, 15);
+ });
+
+ it('should work as an embedded task', function(done) {
+ var retryResult = 'RETRY';
+ var fooResults;
+ var retryResults;
+
+ async.auto({
+ dep: async.constant('dep'),
+ foo: ['dep', function(results, callback){
+ fooResults = results;
+ callback(null, 'FOO');
+ }],
+ retry: ['dep', async.retryable(function(results, callback) {
+ retryResults = results;
+ callback(null, retryResult);
+ })]
+ }, function(err, results){
+ assert.equal(results.retry, retryResult, "Incorrect result was returned from retry function");
+ assert.equal(fooResults, retryResults, "Incorrect results were passed to retry function");
+ done();
+ });
+ });
+
+ it('should work as an embedded task with interval', function(done) {
+ var start = new Date().getTime();
+ var opts = {times: 5, interval: 20};
+
+ async.auto({
+ foo: function(callback){
+ callback(null, 'FOO');
+ },
+ retry: async.retryable(opts, function(callback) {
+ callback('err');
+ })
+ }, function(){
+ var duration = new Date().getTime() - start;
+ var expectedMinimumDuration = (opts.times -1) * opts.interval;
+ assert(duration >= expectedMinimumDuration,
+ "The duration should have been greater than " +
+ expectedMinimumDuration + ", but was " + duration);
+ done();
+ });
+ });
+});
diff --git a/mocha_test/setImmediate.js b/mocha_test/setImmediate.js
new file mode 100644
index 0000000..854111a
--- /dev/null
+++ b/mocha_test/setImmediate.js
@@ -0,0 +1,24 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+
+describe("setImmediate", function () {
+
+ it('basics', function(done){
+ var call_order = [];
+ async.setImmediate(function(){call_order.push('two');});
+ call_order.push('one');
+
+ setTimeout(function(){
+ expect(call_order).to.eql(['one','two']);
+ done();
+ }, 25);
+ });
+
+ it("extra args", function (done) {
+ async.setImmediate(function (a, b, c) {
+ expect([a, b, c]).to.eql([1, 2, 3]);
+ done();
+ }, 1, 2, 3);
+ });
+
+});
diff --git a/mocha_test/some.js b/mocha_test/some.js
index 8bdcb6b..0a5a8da 100644
--- a/mocha_test/some.js
+++ b/mocha_test/some.js
@@ -29,14 +29,14 @@ describe("some", function () {
setTimeout(function(){
call_order.push(x);
callback(null, x === 1);
- }, x*25);
+ }, x*5);
}, function(){
call_order.push('callback');
});
setTimeout(function(){
expect(call_order).to.eql([1,'callback',2,3]);
done();
- }, 100);
+ }, 25);
});
it('some error', function(done){
@@ -49,6 +49,20 @@ describe("some", function () {
});
});
+ it('some no callback', function(done) {
+ var calls = [];
+
+ async.some([1, 2, 3], function (val, cb) {
+ calls.push(val);
+ cb();
+ });
+
+ setTimeout(function () {
+ expect(calls).to.eql([1, 2, 3]);
+ done();
+ }, 10);
+ });
+
it('someLimit true', function(done){
async.someLimit([3,1,2], 2, function(x, callback){
setTimeout(function(){callback(null, x === 2);}, 0);
@@ -87,5 +101,14 @@ describe("some", function () {
expect(async.any).to.equal(async.some);
});
+ it('anyLimit alias', function(){
+ expect(async.anyLimit).to.equal(async.someLimit);
+ });
+
+ it('anySeries alias', function(){
+ expect(async.anySeries).to.be.a('function');
+ expect(async.anySeries).to.equal(async.someSeries);
+ });
+
});
diff --git a/mocha_test/timeout.js b/mocha_test/timeout.js
new file mode 100644
index 0000000..c8b79a7
--- /dev/null
+++ b/mocha_test/timeout.js
@@ -0,0 +1,48 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+
+describe('timeout', function () {
+
+ it('timeout with series', function(done){
+ async.series([
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I didn\'t time out');
+ }, 25);
+ }, 50),
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I will time out');
+ }, 75);
+ }, 50)
+ ],
+ function(err, results) {
+ expect(err.message).to.equal('Callback function timed out.');
+ expect(err.code).to.equal('ETIMEDOUT');
+ expect(results[0]).to.equal('I didn\'t time out');
+ done();
+ });
+ });
+
+ it('timeout with parallel', function(done){
+ async.parallel([
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I didn\'t time out');
+ }, 25);
+ }, 50),
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I will time out');
+ }, 75);
+ }, 50)
+ ],
+ function(err, results) {
+ expect(err.message).to.equal('Callback function timed out.');
+ expect(err.code).to.equal('ETIMEDOUT');
+ expect(results[0]).to.equal('I didn\'t time out');
+ done();
+ });
+ });
+
+});
diff --git a/mocha_test/waterfall.js b/mocha_test/waterfall.js
new file mode 100644
index 0000000..b1d1561
--- /dev/null
+++ b/mocha_test/waterfall.js
@@ -0,0 +1,148 @@
+var async = require('../lib');
+var expect = require('chai').expect;
+
+describe("waterfall", function () {
+
+ it('basics', function(done){
+ var call_order = [];
+ async.waterfall([
+ function(callback){
+ call_order.push('fn1');
+ setTimeout(function(){callback(null, 'one', 'two');}, 0);
+ },
+ function(arg1, arg2, callback){
+ call_order.push('fn2');
+ expect(arg1).to.equal('one');
+ expect(arg2).to.equal('two');
+ setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25);
+ },
+ function(arg1, arg2, arg3, callback){
+ call_order.push('fn3');
+ expect(arg1).to.equal('one');
+ expect(arg2).to.equal('two');
+ expect(arg3).to.equal('three');
+ callback(null, 'four');
+ },
+ function(arg4, callback){
+ call_order.push('fn4');
+ expect(call_order).to.eql(['fn1','fn2','fn3','fn4']);
+ callback(null, 'test');
+ }
+ ], function(err){
+ expect(err === null, err + " passed instead of 'null'");
+ done();
+ });
+ });
+
+ it('empty array', function(done){
+ async.waterfall([], function(err){
+ if (err) throw err;
+ done();
+ });
+ });
+
+ it('non-array', function(done){
+ async.waterfall({}, function(err){
+ expect(err.message).to.equal('First argument to waterfall must be an array of functions');
+ done();
+ });
+ });
+
+ it('no callback', function(done){
+ async.waterfall([
+ function(callback){callback();},
+ function(callback){callback(); done();}
+ ]);
+ });
+
+ it('async', function(done){
+ var call_order = [];
+ async.waterfall([
+ function(callback){
+ call_order.push(1);
+ callback();
+ call_order.push(2);
+ },
+ function(callback){
+ call_order.push(3);
+ callback();
+ },
+ function(){
+ expect(call_order).to.eql([1,3]);
+ done();
+ }
+ ]);
+ });
+
+ it('error', function(done){
+ async.waterfall([
+ function(callback){
+ callback('error');
+ },
+ function(callback){
+ test.ok(false, 'next function should not be called');
+ callback();
+ }
+ ], function(err){
+ expect(err).to.equal('error');
+ done();
+ });
+ });
+
+ it('multiple callback calls', function(){
+ var arr = [
+ function(callback){
+ // call the callback twice. this should call function 2 twice
+ callback(null, 'one', 'two');
+ callback(null, 'one', 'two');
+ },
+ function(arg1, arg2, callback){
+ callback(null, arg1, arg2, 'three');
+ }
+ ];
+ expect(function () {
+ async.waterfall(arr, function () {});
+ }).to.throw(/already called/);
+ });
+
+ it('call in another context', function(done) {
+ if (process.browser) {
+ // node only test
+ done();
+ return;
+ }
+
+ var vm = require('vm');
+ var sandbox = {
+ async: async,
+ done: done
+ };
+
+ var fn = "(" + (function () {
+ async.waterfall([function (callback) {
+ callback();
+ }], function (err) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ }).toString() + "())";
+
+ vm.runInNewContext(fn, sandbox);
+ });
+
+ it('should not use unnecessary deferrals', function (done) {
+ var sameStack = true;
+
+ async.waterfall([
+ function (cb) { cb(null, 1); },
+ function (arg, cb) { cb(); }
+ ], function() {
+ expect(sameStack).to.equal(true);
+ done();
+ });
+
+ sameStack = false;
+ });
+});
diff --git a/package.json b/package.json
index 76f9fac..60cad6a 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
- "version": "2.0.0-alpha",
+ "version": "2.0.0-rc.2",
"main": "dist/async.js",
"author": "Caolan McMahon",
"repository": {
@@ -33,8 +33,6 @@
"chai": "^3.1.0",
"coveralls": "^2.11.2",
"es6-promise": "^2.3.0",
- "fs-extra": "^0.26.3",
- "gulp": "~3.9.0",
"jscs": "^1.13.1",
"jshint": "~2.8.0",
"karma": "^0.13.2",
@@ -49,23 +47,22 @@
"recursive-readdir": "^1.3.0",
"rimraf": "^2.5.0",
"rollup": "^0.25.0",
+ "rollup-plugin-node-resolve": "^1.5.0",
"rollup-plugin-npm": "~1.3.0",
"rsvp": "^3.0.18",
"semver": "^4.3.6",
"uglify-js": "~2.4.0",
- "vinyl-buffer": "~1.0.0",
- "vinyl-source-stream": "~1.1.0",
"yargs": "~3.9.1"
},
"scripts": {
"coverage": "nyc npm test && nyc report",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
- "lint": "jshint lib/ test/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ gulpfile.js karma.conf.js && jscs lib/ test/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ gulpfile.js karma.conf.js",
+ "lint": "jshint lib/ test/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js && jscs lib/ test/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js",
"mocha-browser-test": "karma start",
"mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register",
"mocha-test": "npm run mocha-node-test && npm run mocha-browser-test",
"nodeunit-test": "nodeunit test/test-async.js",
- "test": "npm run-script lint && npm run nodeunit-test && npm run mocha-test"
+ "test": "npm run-script lint && npm run nodeunit-test && npm run mocha-node-test"
},
"license": "MIT",
"jam": {
@@ -92,4 +89,4 @@
"tests"
]
}
-} \ No newline at end of file
+}
diff --git a/support/build.test.js b/support/build.test.js
index 141909a..cc56348 100644
--- a/support/build.test.js
+++ b/support/build.test.js
@@ -2,7 +2,7 @@
var methods = ["each", "waterfall", "queue", "eachSeries"];
var expect = require('chai').expect;
var rollup = require('rollup').rollup;
-var rollupPluginNpm = require('rollup-plugin-npm');
+var rollupPluginNodeResolve = require('rollup-plugin-node-resolve');
var fs = require('fs');
var exec = require('child_process').exec;
@@ -76,7 +76,7 @@ describe("ES Modules", function () {
return rollup({
entry: __dirname + "/es.test.js",
plugins: [
- rollupPluginNpm()
+ rollupPluginNodeResolve()
]
}).then(function (bundle) {
return bundle.write({
diff --git a/support/xyz.sh b/support/xyz.sh
index 8fd8d2d..e178eee 100755
--- a/support/xyz.sh
+++ b/support/xyz.sh
@@ -84,7 +84,7 @@ while (($# > 0)) ; do
exit
;;
-v|--version)
- node -p "require('$dir/package.json').version"
+ node -p "require('$dir/../package.json').version"
exit
;;
-b|--branch) branch="$1" ; shift ;;
@@ -117,7 +117,7 @@ name=$(node -p "require('./package.json').name" 2>/dev/null) ||
version=$(node -p "require('./package.json').version" 2>/dev/null) ||
(echo "Cannot read package version" >&2 ; exit 1)
-next_version=$("$dir/node_modules/.bin/semver" -i "$increment" "$version") ||
+next_version=$("$dir/../node_modules/.bin/semver" -i "$increment" "$version") ||
(echo "Cannot increment version number" >&2 ; exit 1)
message="${message_template//X.Y.Z/$next_version}"
@@ -160,7 +160,7 @@ inc() {
inc package.json
-run "./sync-package-managers.js"
+run "$dir/sync-package-managers.js"
run "git add --force *.json"
run "git commit --message '$message'"
diff --git a/test/test-async.js b/test/test-async.js
index bd103bf..6831ac2 100755
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -1,6 +1,6 @@
/**
* NOTE: We are in the process of migrating these tests to Mocha. If you are
- * adding a new test, consider creating a new spec file in mocha_tests/
+ * adding a new test, please create a new spec file in mocha_tests/
*/
require('babel-core/register');
@@ -16,34 +16,34 @@ if (!Function.prototype.bind) {
};
}
-function eachIterator(args, x, callback) {
+function eachIteratee(args, x, callback) {
setTimeout(function(){
args.push(x);
callback();
}, x*25);
}
-function forEachOfIterator(args, value, key, callback) {
+function forEachOfIteratee(args, value, key, callback) {
setTimeout(function(){
args.push(key, value);
callback();
}, value*25);
}
-function mapIterator(call_order, x, callback) {
+function mapIteratee(call_order, x, callback) {
setTimeout(function(){
call_order.push(x);
callback(null, x*2);
}, x*25);
}
-function eachNoCallbackIterator(test, x, callback) {
+function eachNoCallbackIteratee(test, x, callback) {
test.equal(x, 1);
callback();
test.done();
}
-function forEachOfNoCallbackIterator(test, x, key, callback) {
+function forEachOfNoCallbackIteratee(test, x, key, callback) {
test.equal(x, 1);
test.equal(key, "a");
callback();
@@ -278,267 +278,6 @@ exports['seq without callback'] = function (test) {
add2mul3.call(testcontext, 3);
};
-// Issue 306 on github: https://github.com/caolan/async/issues/306
-exports['retry when attempt succeeds'] = function(test) {
- var failed = 3;
- var callCount = 0;
- var expectedResult = 'success';
- function fn(callback) {
- callCount++;
- failed--;
- if (!failed) callback(null, expectedResult);
- else callback(true); // respond with error
- }
- async.retry(fn, function(err, result){
- test.ok(err === null, err + " passed instead of 'null'");
- test.equal(callCount, 3, 'did not retry the correct number of times');
- test.equal(result, expectedResult, 'did not return the expected result');
- test.done();
- });
-};
-
-exports['retry when all attempts succeeds'] = function(test) {
- var times = 3;
- var callCount = 0;
- var error = 'ERROR';
- var erroredResult = 'RESULT';
- function fn(callback) {
- callCount++;
- callback(error + callCount, erroredResult + callCount); // respond with indexed values
- }
- async.retry(times, fn, function(err, result){
- test.equal(callCount, 3, "did not retry the correct number of times");
- test.equal(err, error + times, "Incorrect error was returned");
- test.equal(result, erroredResult + times, "Incorrect result was returned");
- test.done();
- });
-};
-
-exports['retry fails with invalid arguments'] = function(test) {
- test.throws(function() {
- async.retry("");
- });
- test.throws(function() {
- async.retry();
- });
- test.throws(function() {
- async.retry(function() {}, 2, function() {});
- });
- test.done();
-};
-
-exports['retry with interval when all attempts succeeds'] = function(test) {
- var times = 3;
- var interval = 500;
- var callCount = 0;
- var error = 'ERROR';
- var erroredResult = 'RESULT';
- function fn(callback) {
- callCount++;
- callback(error + callCount, erroredResult + callCount); // respond with indexed values
- }
- var start = new Date().getTime();
- async.retry({ times: times, interval: interval}, fn, function(err, result){
- var now = new Date().getTime();
- var duration = now - start;
- test.ok(duration > (interval * (times -1)), 'did not include interval');
- test.equal(callCount, 3, "did not retry the correct number of times");
- test.equal(err, error + times, "Incorrect error was returned");
- test.equal(result, erroredResult + times, "Incorrect result was returned");
- test.done();
- });
-};
-
-// need to fix retry, this isn't working
-/*
-exports['retry as an embedded task'] = function(test) {
- var retryResult = 'RETRY';
- var fooResults;
- var retryResults;
-
- async.auto({
- dep: async.constant('dep'),
- foo: ['dep', function(results, callback){
- fooResults = results;
- callback(null, 'FOO');
- }],
- retry: ['dep', async.retry(function(results, callback) {
- retryResults = results;
- callback(null, retryResult);
- })]
- }, function(err, results){
- test.equal(results.retry, retryResult, "Incorrect result was returned from retry function");
- test.equal(fooResults, retryResults, "Incorrect results were passed to retry function");
- test.done();
- });
-};*/
-
-exports['retry as an embedded task with interval'] = function(test) {
- var start = new Date().getTime();
- var opts = {times: 5, interval: 100};
-
- async.auto({
- foo: function(callback){
- callback(null, 'FOO');
- },
- retry: async.retry(opts, function(callback) {
- callback('err');
- })
- }, function(){
- var duration = new Date().getTime() - start;
- var expectedMinimumDuration = (opts.times -1) * opts.interval;
- test.ok(duration >= expectedMinimumDuration, "The duration should have been greater than " + expectedMinimumDuration + ", but was " + duration);
- test.done();
- });
-};
-
-exports['waterfall'] = {
-
- 'basic': function(test){
- test.expect(7);
- var call_order = [];
- async.waterfall([
- function(callback){
- call_order.push('fn1');
- setTimeout(function(){callback(null, 'one', 'two');}, 0);
- },
- function(arg1, arg2, callback){
- call_order.push('fn2');
- test.equals(arg1, 'one');
- test.equals(arg2, 'two');
- setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25);
- },
- function(arg1, arg2, arg3, callback){
- call_order.push('fn3');
- test.equals(arg1, 'one');
- test.equals(arg2, 'two');
- test.equals(arg3, 'three');
- callback(null, 'four');
- },
- function(arg4, callback){
- call_order.push('fn4');
- test.same(call_order, ['fn1','fn2','fn3','fn4']);
- callback(null, 'test');
- }
- ], function(err){
- test.ok(err === null, err + " passed instead of 'null'");
- test.done();
- });
-},
-
- 'empty array': function(test){
- async.waterfall([], function(err){
- if (err) throw err;
- test.done();
- });
-},
-
- 'non-array': function(test){
- async.waterfall({}, function(err){
- test.equals(err.message, 'First argument to waterfall must be an array of functions');
- test.done();
- });
-},
-
- 'no callback': function(test){
- async.waterfall([
- function(callback){callback();},
- function(callback){callback(); test.done();}
- ]);
-},
-
- 'async': function(test){
- var call_order = [];
- async.waterfall([
- function(callback){
- call_order.push(1);
- callback();
- call_order.push(2);
- },
- function(callback){
- call_order.push(3);
- callback();
- },
- function(){
- test.same(call_order, [1,2,3]);
- test.done();
- }
- ]);
-},
-
- 'error': function(test){
- test.expect(1);
- async.waterfall([
- function(callback){
- callback('error');
- },
- function(callback){
- test.ok(false, 'next function should not be called');
- callback();
- }
- ], function(err){
- test.equals(err, 'error');
- });
- setTimeout(test.done, 50);
-},
-
- 'multiple callback calls': function(test){
- var call_order = [];
- var arr = [
- function(callback){
- call_order.push(1);
- // call the callback twice. this should call function 2 twice
- callback(null, 'one', 'two');
- callback(null, 'one', 'two');
- },
- function(arg1, arg2, callback){
- call_order.push(2);
- callback(null, arg1, arg2, 'three');
- },
- function(arg1, arg2, arg3, callback){
- call_order.push(3);
- callback(null, 'four');
- },
- function(/*arg4*/){
- call_order.push(4);
- arr[3] = function(){
- call_order.push(4);
- test.same(call_order, [1,2,2,3,3,4,4]);
- test.done();
- };
- }
- ];
- async.waterfall(arr);
-},
-
- 'call in another context': function(test) {
- if (isBrowser()) {
- // node only test
- test.done();
- return;
- }
-
- var vm = require('vm');
- var sandbox = {
- async: async,
- test: test
- };
-
- var fn = "(" + (function () {
- async.waterfall([function (callback) {
- callback();
- }], function (err) {
- if (err) {
- return test.done(err);
- }
- test.done();
- });
- }).toString() + "())";
-
- vm.runInNewContext(fn, sandbox);
-}
-
-};
exports['parallel'] = function(test){
var call_order = [];
@@ -752,6 +491,29 @@ exports['parallel call in another context'] = function(test) {
vm.runInNewContext(fn, sandbox);
};
+exports['parallel error with reflect'] = function(test){
+ async.parallel([
+ async.reflect(function(callback){
+ callback('error', 1);
+ }),
+ async.reflect(function(callback){
+ callback('error2', 2);
+ }),
+ async.reflect(function(callback){
+ callback(null, 2);
+ })
+ ],
+ function(err, results){
+ test.ok(err === null, err + " passed instead of 'null'");
+ test.same(results, [
+ { error: 'error' },
+ { error: 'error2' },
+ { value: 2 }
+ ]);
+ test.done();
+ });
+};
+
exports['parallel does not continue replenishing after error'] = function (test) {
var started = 0;
var arr = [
@@ -819,6 +581,40 @@ exports['series'] = {
});
},
+ 'with reflect': function(test){
+ var call_order = [];
+ async.series([
+ async.reflect(function(callback){
+ setTimeout(function(){
+ call_order.push(1);
+ callback(null, 1);
+ }, 25);
+ }),
+ async.reflect(function(callback){
+ setTimeout(function(){
+ call_order.push(2);
+ callback(null, 2);
+ }, 50);
+ }),
+ async.reflect(function(callback){
+ setTimeout(function(){
+ call_order.push(3);
+ callback(null, 3,3);
+ }, 15);
+ })
+ ],
+ function(err, results){
+ test.ok(err === null, err + " passed instead of 'null'");
+ test.deepEqual(results, [
+ { value: 1 },
+ { value: 2 },
+ { value: [3,3] }
+ ]);
+ test.same(call_order, [1,2,3]);
+ test.done();
+ });
+},
+
'empty array': function(test){
async.series([], function(err, results){
test.equals(err, null);
@@ -844,6 +640,30 @@ exports['series'] = {
setTimeout(test.done, 100);
},
+ 'error with reflect': function(test){
+ test.expect(2);
+ async.series([
+ async.reflect(function(callback){
+ callback('error', 1);
+ }),
+ async.reflect(function(callback){
+ callback('error2', 2);
+ }),
+ async.reflect(function(callback){
+ callback(null, 1);
+ })
+ ],
+ function(err, results){
+ test.ok(err === null, err + " passed instead of 'null'");
+ test.deepEqual(results, [
+ { error: 'error' },
+ { error: 'error2' },
+ { value: 1 }
+ ]);
+ test.done();
+ });
+},
+
'no callback': function(test){
async.series([
function(callback){callback();},
@@ -987,7 +807,7 @@ exports['iterator.next'] = function(test){
exports['each'] = function(test){
var args = [];
- async.each([1,3,2], eachIterator.bind(this, args), function(err){
+ async.each([1,3,2], eachIteratee.bind(this, args), function(err){
test.ok(err === null, err + " passed instead of 'null'");
test.same(args, [1,2,3]);
test.done();
@@ -1010,7 +830,7 @@ exports['each extra callback'] = function(test){
exports['each empty array'] = function(test){
test.expect(1);
async.each([], function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1025,7 +845,7 @@ exports['each empty array, with other property on the array'] = function(test){
var myArray = [];
myArray.myProp = "anything";
async.each(myArray, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1046,7 +866,7 @@ exports['each error'] = function(test){
};
exports['each no callback'] = function(test){
- async.each([1], eachNoCallbackIterator.bind(this, test));
+ async.each([1], eachNoCallbackIteratee.bind(this, test));
};
exports['forEach alias'] = function (test) {
@@ -1056,7 +876,7 @@ exports['forEach alias'] = function (test) {
exports['forEachOf'] = function(test){
var args = [];
- async.forEachOf({ a: 1, b: 2 }, forEachOfIterator.bind(this, args), function(err){
+ async.forEachOf({ a: 1, b: 2 }, forEachOfIteratee.bind(this, args), function(err){
test.ok(err === null, err + " passed instead of 'null'");
test.same(args, ["a", 1, "b", 2]);
test.done();
@@ -1079,7 +899,7 @@ exports['forEachOf - instant resolver'] = function(test){
exports['forEachOf empty object'] = function(test){
test.expect(1);
async.forEachOf({}, function(value, key, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err) {
if (err) throw err;
@@ -1091,7 +911,7 @@ exports['forEachOf empty object'] = function(test){
exports['forEachOf empty array'] = function(test){
test.expect(1);
async.forEachOf([], function(value, key, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err) {
if (err) throw err;
@@ -1111,7 +931,7 @@ exports['forEachOf error'] = function(test){
};
exports['forEachOf no callback'] = function(test){
- async.forEachOf({ a: 1 }, forEachOfNoCallbackIterator.bind(this, test));
+ async.forEachOf({ a: 1 }, forEachOfNoCallbackIteratee.bind(this, test));
};
exports['eachOf alias'] = function(test){
@@ -1121,16 +941,46 @@ exports['eachOf alias'] = function(test){
exports['forEachOf with array'] = function(test){
var args = [];
- async.forEachOf([ "a", "b" ], forEachOfIterator.bind(this, args), function(err){
+ async.forEachOf([ "a", "b" ], forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, "a", 1, "b"]);
+ test.done();
+ });
+};
+
+exports['forEachOf with Set (iterators)'] = function(test){
+ if (typeof Set !== 'function')
+ return test.done();
+
+ var args = [];
+ var set = new Set();
+ set.add("a");
+ set.add("b");
+ async.forEachOf(set, forEachOfIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, [0, "a", 1, "b"]);
test.done();
});
};
+exports['forEachOf with Map (iterators)'] = function(test){
+ if (typeof Map !== 'function')
+ return test.done();
+
+ var args = [];
+ var map = new Map();
+ map.set(1, "a");
+ map.set(2, "b");
+ async.forEachOf(map, forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, [1, "a"], 1, [2, "b"]]);
+ test.done();
+ });
+};
+
exports['eachSeries'] = function(test){
var args = [];
- async.eachSeries([1,3,2], eachIterator.bind(this, args), function(err){
+ async.eachSeries([1,3,2], eachIteratee.bind(this, args), function(err){
test.ok(err === null, err + " passed instead of 'null'");
test.same(args, [1,3,2]);
test.done();
@@ -1140,7 +990,7 @@ exports['eachSeries'] = function(test){
exports['eachSeries empty array'] = function(test){
test.expect(1);
async.eachSeries([], function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1204,7 +1054,7 @@ exports['eachSeries error'] = function(test){
};
exports['eachSeries no callback'] = function(test){
- async.eachSeries([1], eachNoCallbackIterator.bind(this, test));
+ async.eachSeries([1], eachNoCallbackIteratee.bind(this, test));
};
@@ -1226,7 +1076,7 @@ exports['eachLimit'] = function(test){
exports['eachLimit empty array'] = function(test){
test.expect(1);
async.eachLimit([], 2, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1238,7 +1088,7 @@ exports['eachLimit empty array'] = function(test){
exports['eachLimit limit exceeds size'] = function(test){
var args = [];
var arr = [0,1,2,3,4,5,6,7,8,9];
- async.eachLimit(arr, 20, eachIterator.bind(this, args), function(err){
+ async.eachLimit(arr, 20, eachIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, arr);
test.done();
@@ -1248,7 +1098,7 @@ exports['eachLimit limit exceeds size'] = function(test){
exports['eachLimit limit equal size'] = function(test){
var args = [];
var arr = [0,1,2,3,4,5,6,7,8,9];
- async.eachLimit(arr, 10, eachIterator.bind(this, args), function(err){
+ async.eachLimit(arr, 10, eachIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, arr);
test.done();
@@ -1258,7 +1108,7 @@ exports['eachLimit limit equal size'] = function(test){
exports['eachLimit zero limit'] = function(test){
test.expect(1);
async.eachLimit([0,1,2,3,4,5], 0, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1285,7 +1135,7 @@ exports['eachLimit error'] = function(test){
};
exports['eachLimit no callback'] = function(test){
- async.eachLimit([1], 1, eachNoCallbackIterator.bind(this, test));
+ async.eachLimit([1], 1, eachNoCallbackIteratee.bind(this, test));
};
exports['eachLimit synchronous'] = function(test){
@@ -1332,7 +1182,7 @@ exports['forEachSeries alias'] = function (test) {
exports['forEachOfSeries'] = function(test){
var args = [];
- async.forEachOfSeries({ a: 1, b: 2 }, forEachOfIterator.bind(this, args), function(err){
+ async.forEachOfSeries({ a: 1, b: 2 }, forEachOfIteratee.bind(this, args), function(err){
test.ok(err === null, err + " passed instead of 'null'");
test.same(args, [ "a", 1, "b", 2 ]);
test.done();
@@ -1342,7 +1192,7 @@ exports['forEachOfSeries'] = function(test){
exports['forEachOfSeries empty object'] = function(test){
test.expect(1);
async.forEachOfSeries({}, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1365,18 +1215,47 @@ exports['forEachOfSeries error'] = function(test){
};
exports['forEachOfSeries no callback'] = function(test){
- async.forEachOfSeries({ a: 1 }, forEachOfNoCallbackIterator.bind(this, test));
+ async.forEachOfSeries({ a: 1 }, forEachOfNoCallbackIteratee.bind(this, test));
};
exports['forEachOfSeries with array'] = function(test){
var args = [];
- async.forEachOfSeries([ "a", "b" ], forEachOfIterator.bind(this, args), function(err){
+ async.forEachOfSeries([ "a", "b" ], forEachOfIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, [ 0, "a", 1, "b" ]);
test.done();
});
};
+exports['forEachOfSeries with Set (iterators)'] = function(test){
+ if (typeof Set !== 'function')
+ return test.done();
+
+ var args = [];
+ var set = new Set();
+ set.add("a");
+ set.add("b");
+ async.forEachOfSeries(set, forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, "a", 1, "b"]);
+ test.done();
+ });
+};
+
+exports['forEachOfSeries with Map (iterators)'] = function(test){
+ if (typeof Map !== 'function')
+ return test.done();
+
+ var args = [];
+ var map = new Map();
+ map.set(1, "a");
+ map.set(2, "b");
+ async.forEachOfSeries(map, forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, [1, "a"], 1, [2, "b"]]);
+ test.done();
+ });
+};
exports['eachOfLimit alias'] = function(test){
test.equals(async.eachOfLimit, async.forEachOfLimit);
@@ -1412,7 +1291,7 @@ exports['forEachOfLimit'] = function(test){
exports['forEachOfLimit empty object'] = function(test){
test.expect(1);
async.forEachOfLimit({}, 2, function(value, key, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1424,7 +1303,7 @@ exports['forEachOfLimit empty object'] = function(test){
exports['forEachOfLimit limit exceeds size'] = function(test){
var args = [];
var obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- async.forEachOfLimit(obj, 10, forEachOfIterator.bind(this, args), function(err){
+ async.forEachOfLimit(obj, 10, forEachOfIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, [ "a", 1, "b", 2, "c", 3, "d", 4, "e", 5 ]);
test.done();
@@ -1434,7 +1313,7 @@ exports['forEachOfLimit limit exceeds size'] = function(test){
exports['forEachOfLimit limit equal size'] = function(test){
var args = [];
var obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- async.forEachOfLimit(obj, 5, forEachOfIterator.bind(this, args), function(err){
+ async.forEachOfLimit(obj, 5, forEachOfIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, [ "a", 1, "b", 2, "c", 3, "d", 4, "e", 5 ]);
test.done();
@@ -1444,7 +1323,7 @@ exports['forEachOfLimit limit equal size'] = function(test){
exports['forEachOfLimit zero limit'] = function(test){
test.expect(1);
async.forEachOfLimit({ a: 1, b: 2 }, 0, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1471,13 +1350,13 @@ exports['forEachOfLimit error'] = function(test){
};
exports['forEachOfLimit no callback'] = function(test){
- async.forEachOfLimit({ a: 1 }, 1, forEachOfNoCallbackIterator.bind(this, test));
+ async.forEachOfLimit({ a: 1 }, 1, forEachOfNoCallbackIteratee.bind(this, test));
};
exports['forEachOfLimit synchronous'] = function(test){
var args = [];
var obj = { a: 1, b: 2 };
- async.forEachOfLimit(obj, 5, forEachOfIterator.bind(this, args), function(err){
+ async.forEachOfLimit(obj, 5, forEachOfIteratee.bind(this, args), function(err){
if (err) throw err;
test.same(args, [ "a", 1, "b", 2 ]);
test.done();
@@ -1487,18 +1366,48 @@ exports['forEachOfLimit synchronous'] = function(test){
exports['forEachOfLimit with array'] = function(test){
var args = [];
var arr = [ "a", "b" ];
- async.forEachOfLimit(arr, 1, forEachOfIterator.bind(this, args), function (err) {
+ async.forEachOfLimit(arr, 1, forEachOfIteratee.bind(this, args), function (err) {
if (err) throw err;
test.same(args, [ 0, "a", 1, "b" ]);
test.done();
});
};
+exports['forEachOfLimit with Set (iterators)'] = function(test){
+ if (typeof Set !== 'function')
+ return test.done();
+
+ var args = [];
+ var set = new Set();
+ set.add("a");
+ set.add("b");
+ async.forEachOfLimit(set, 1, forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, "a", 1, "b"]);
+ test.done();
+ });
+};
+
+exports['forEachOfLimit with Map (iterators)'] = function(test){
+ if (typeof Map !== 'function')
+ return test.done();
+
+ var args = [];
+ var map = new Map();
+ map.set(1, "a");
+ map.set(2, "b");
+ async.forEachOfLimit(map, 1, forEachOfIteratee.bind(this, args), function(err){
+ if (err) throw err;
+ test.same(args, [0, [1, "a"], 1, [2, "b"]]);
+ test.done();
+ });
+};
+
exports['map'] = {
'basic': function(test){
var call_order = [];
- async.map([1,3,2], mapIterator.bind(this, call_order), function(err, results){
+ async.map([1,3,2], mapIteratee.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
test.same(call_order, [1,2,3]);
test.same(results, [2,6,4]);
@@ -1506,6 +1415,50 @@ exports['map'] = {
});
},
+ 'with reflect': function(test){
+ var call_order = [];
+ async.map([1,3,2], async.reflect(function(item, cb) {
+ setTimeout(function(){
+ call_order.push(item);
+ cb(null, item*2);
+ }, item*25);
+ }), function(err, results){
+ test.ok(err === null, err + " passed instead of 'null'");
+ test.same(call_order, [1,2,3]);
+ test.same(results, [
+ { value: 2 },
+ { value: 6 },
+ { value: 4 }
+ ]);
+ test.done();
+ });
+},
+
+ 'error with reflect': function(test){
+ var call_order = [];
+ async.map([-1,1,3,2], async.reflect(function(item, cb) {
+ setTimeout(function(){
+ call_order.push(item);
+ if (item < 0) {
+ cb('number less then zero');
+ } else {
+ cb(null, item*2);
+ }
+
+ }, item*25);
+ }), function(err, results){
+ test.ok(err === null, err + " passed instead of 'null'");
+ test.same(call_order, [-1,1,2,3]);
+ test.same(results, [
+ { error: 'number less then zero' },
+ { value: 2 },
+ { value: 6 },
+ { value: 4 }
+ ]);
+ test.done();
+ });
+},
+
'map original untouched': function(test){
var a = [1,2,3];
async.map(a, function(x, callback){
@@ -1565,7 +1518,7 @@ exports['map'] = {
'mapSeries': function(test){
var call_order = [];
- async.mapSeries([1,3,2], mapIterator.bind(this, call_order), function(err, results){
+ async.mapSeries([1,3,2], mapIteratee.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
test.same(call_order, [1,3,2]);
test.same(results, [2,6,4]);
@@ -1606,7 +1559,7 @@ exports['map'] = {
'mapLimit': function(test){
var call_order = [];
- async.mapLimit([2,4,3], 2, mapIterator.bind(this, call_order), function(err, results){
+ async.mapLimit([2,4,3], 2, mapIteratee.bind(this, call_order), function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
test.same(call_order, [2,4,3]);
test.same(results, [4,8,6]);
@@ -1617,7 +1570,7 @@ exports['map'] = {
'mapLimit empty array': function(test){
test.expect(1);
async.mapLimit([], 2, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -1639,7 +1592,7 @@ exports['map'] = {
'mapLimit limit exceeds size': function(test){
var call_order = [];
- async.mapLimit([0,1,2,3,4,5,6,7,8,9], 20, mapIterator.bind(this, call_order), function(err, results){
+ async.mapLimit([0,1,2,3,4,5,6,7,8,9], 20, mapIteratee.bind(this, call_order), function(err, results){
test.same(call_order, [0,1,2,3,4,5,6,7,8,9]);
test.same(results, [0,2,4,6,8,10,12,14,16,18]);
test.done();
@@ -1648,7 +1601,7 @@ exports['map'] = {
'mapLimit limit equal size': function(test){
var call_order = [];
- async.mapLimit([0,1,2,3,4,5,6,7,8,9], 10, mapIterator.bind(this, call_order), function(err, results){
+ async.mapLimit([0,1,2,3,4,5,6,7,8,9], 10, mapIteratee.bind(this, call_order), function(err, results){
test.same(call_order, [0,1,2,3,4,5,6,7,8,9]);
test.same(results, [0,2,4,6,8,10,12,14,16,18]);
test.done();
@@ -1658,7 +1611,7 @@ exports['map'] = {
'mapLimit zero limit': function(test){
test.expect(2);
async.mapLimit([0,1,2,3,4,5], 0, function(x, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err, results){
test.same(results, []);
@@ -1705,6 +1658,21 @@ exports['map'] = {
test.equal(started, 3);
test.done();
}, maxTime);
+},
+
+ 'map with Map': function(test) {
+ if (typeof Map !== 'function')
+ return test.done();
+
+ var map = new Map();
+ map.set(1, "a");
+ map.set(2, "b");
+ async.map(map, function(val, cb) {
+ cb(null, val);
+ }, function (err, result) {
+ test.ok(Array.isArray(result), "map should return an array for an iterable");
+ test.done();
+ });
}
};
@@ -1971,7 +1939,7 @@ exports['times'] = {
'times 0': function(test){
test.expect(1);
async.times(0, function(n, callback){
- test.ok(false, 'iterator should not be called');
+ test.ok(false, 'iteratee should not be called');
callback();
}, function(err){
if (err) throw err;
@@ -2042,38 +2010,11 @@ console_fn_tests('dir');
console_fn_tests('warn');
console_fn_tests('error');*/
-exports['nextTick'] = function(test){
- test.expect(1);
- var call_order = [];
- async.nextTick(function(){call_order.push('two');});
- call_order.push('one');
- setTimeout(function(){
- test.same(call_order, ['one','two']);
- test.done();
- }, 50);
-};
-
-exports['nextTick in the browser'] = function(test){
- if (!isBrowser()) {
- // skip this test in node
- return test.done();
- }
- test.expect(1);
-
- var call_order = [];
- async.nextTick(function(){call_order.push('two');});
-
- call_order.push('one');
- setTimeout(function(){
- test.same(call_order, ['one','two']);
- }, 50);
- setTimeout(test.done, 100);
-};
exports['concat'] = function(test){
test.expect(3);
var call_order = [];
- var iterator = function (x, cb) {
+ var iteratee = function (x, cb) {
setTimeout(function(){
call_order.push(x);
var r = [];
@@ -2084,7 +2025,7 @@ exports['concat'] = function(test){
cb(null, r);
}, x*25);
};
- async.concat([1,3,2], iterator, function(err, results){
+ async.concat([1,3,2], iteratee, function(err, results){
test.same(results, [1,2,1,3,2,1]);
test.same(call_order, [1,2,3]);
test.ok(err === null, err + " passed instead of 'null'");
@@ -2094,10 +2035,10 @@ exports['concat'] = function(test){
exports['concat error'] = function(test){
test.expect(1);
- var iterator = function (x, cb) {
+ var iteratee = function (x, cb) {
cb(new Error('test error'));
};
- async.concat([1,2,3], iterator, function(err){
+ async.concat([1,2,3], iteratee, function(err){
test.ok(err);
test.done();
});
@@ -2106,7 +2047,7 @@ exports['concat error'] = function(test){
exports['concatSeries'] = function(test){
test.expect(3);
var call_order = [];
- var iterator = function (x, cb) {
+ var iteratee = function (x, cb) {
setTimeout(function(){
call_order.push(x);
var r = [];
@@ -2117,7 +2058,7 @@ exports['concatSeries'] = function(test){
cb(null, r);
}, x*25);
};
- async.concatSeries([1,3,2], iterator, function(err, results){
+ async.concatSeries([1,3,2], iteratee, function(err, results){
test.same(results, [1,3,2,1,2,1]);
test.same(call_order, [1,3,2]);
test.ok(err === null, err + " passed instead of 'null'");
@@ -2136,7 +2077,7 @@ exports['until'] = function (test) {
return (count == 5);
},
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2145,11 +2086,11 @@ exports['until'] = function (test) {
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
['test', 0],
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5],
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5],
]);
test.equals(count, 5);
test.done();
@@ -2164,7 +2105,7 @@ exports['doUntil'] = function (test) {
var count = 0;
async.doUntil(
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2176,11 +2117,11 @@ exports['doUntil'] = function (test) {
test.ok(err === null, err + " passed instead of 'null'");
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5]
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5]
]);
test.equals(count, 5);
test.done();
@@ -2195,7 +2136,7 @@ exports['doUntil callback params'] = function (test) {
var count = 0;
async.doUntil(
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2207,11 +2148,11 @@ exports['doUntil callback params'] = function (test) {
if (err) throw err;
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5]
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5]
]);
test.equals(count, 5);
test.done();
@@ -2231,7 +2172,7 @@ exports['whilst'] = function (test) {
return (count < 5);
},
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2240,11 +2181,11 @@ exports['whilst'] = function (test) {
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
['test', 0],
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5],
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5],
]);
test.equals(count, 5);
test.done();
@@ -2259,7 +2200,7 @@ exports['doWhilst'] = function (test) {
var count = 0;
async.doWhilst(
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2271,11 +2212,11 @@ exports['doWhilst'] = function (test) {
test.ok(err === null, err + " passed instead of 'null'");
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5]
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5]
]);
test.equals(count, 5);
test.done();
@@ -2289,7 +2230,7 @@ exports['doWhilst callback params'] = function (test) {
var count = 0;
async.doWhilst(
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb(null, count);
},
@@ -2301,11 +2242,11 @@ exports['doWhilst callback params'] = function (test) {
if (err) throw err;
test.equals(result, 5, 'last result passed through');
test.same(call_order, [
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5]
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5]
]);
test.equals(count, 5);
test.done();
@@ -2339,7 +2280,7 @@ exports['during'] = function (test) {
cb(null, count < 5);
},
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb();
},
@@ -2347,11 +2288,11 @@ exports['during'] = function (test) {
test.ok(err === null, err + " passed instead of 'null'");
test.same(call_order, [
['test', 0],
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5],
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5],
]);
test.equals(count, 5);
test.done();
@@ -2365,7 +2306,7 @@ exports['doDuring'] = function (test) {
var count = 0;
async.doDuring(
function (cb) {
- call_order.push(['iterator', count]);
+ call_order.push(['iteratee', count]);
count++;
cb();
},
@@ -2376,11 +2317,11 @@ exports['doDuring'] = function (test) {
function (err) {
test.ok(err === null, err + " passed instead of 'null'");
test.same(call_order, [
- ['iterator', 0], ['test', 1],
- ['iterator', 1], ['test', 2],
- ['iterator', 2], ['test', 3],
- ['iterator', 3], ['test', 4],
- ['iterator', 4], ['test', 5],
+ ['iteratee', 0], ['test', 1],
+ ['iteratee', 1], ['test', 2],
+ ['iteratee', 2], ['test', 3],
+ ['iteratee', 3], ['test', 4],
+ ['iteratee', 4], ['test', 5],
]);
test.equals(count, 5);
test.done();
@@ -2404,7 +2345,7 @@ exports['doDuring - error test'] = function (test) {
);
};
-exports['doDuring - error iterator'] = function (test) {
+exports['doDuring - error iteratee'] = function (test) {
test.expect(1);
var error = new Error('asdas');
@@ -2435,1004 +2376,6 @@ exports['whilst optional callback'] = function (test) {
test.done();
};
-exports['queue'] = {
-
- 'queue': function (test) {
- test.expect(17);
-
- var call_order = [],
- delays = [160,80,240,80];
-
- // worker1: --1-4
- // worker2: -2---3
- // order of completion: 2,1,4,3
-
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- callback('error', 'arg');
- }, delays.splice(0,1)[0]);
- }, 2);
-
- q.push(1, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 1);
- call_order.push('callback ' + 1);
- });
- q.push(2, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 2);
- call_order.push('callback ' + 2);
- });
- q.push(3, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 3);
- });
- q.push(4, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 4);
- });
- test.equal(q.length(), 4);
- test.equal(q.concurrency, 2);
-
- q.drain = function () {
- test.same(call_order, [
- 'process 2', 'callback 2',
- 'process 1', 'callback 1',
- 'process 4', 'callback 4',
- 'process 3', 'callback 3'
- ]);
- test.equal(q.concurrency, 2);
- test.equal(q.length(), 0);
- test.done();
- };
-},
-
- 'default concurrency': function (test) {
- test.expect(17);
- var call_order = [],
- delays = [160,80,240,80];
-
- // order of completion: 1,2,3,4
-
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- callback('error', 'arg');
- }, delays.splice(0,1)[0]);
- });
-
- q.push(1, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 3);
- call_order.push('callback ' + 1);
- });
- q.push(2, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 2);
- call_order.push('callback ' + 2);
- });
- q.push(3, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 1);
- call_order.push('callback ' + 3);
- });
- q.push(4, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 4);
- });
- test.equal(q.length(), 4);
- test.equal(q.concurrency, 1);
-
- q.drain = function () {
- test.same(call_order, [
- 'process 1', 'callback 1',
- 'process 2', 'callback 2',
- 'process 3', 'callback 3',
- 'process 4', 'callback 4'
- ]);
- test.equal(q.concurrency, 1);
- test.equal(q.length(), 0);
- test.done();
- };
-},
-
- 'zero concurrency': function(test){
- test.expect(1);
- test.throws(function () {
- async.queue(function (task, callback) {
- callback(null, task);
- }, 0);
- });
- test.done();
-},
-
- 'error propagation': function(test){
- test.expect(1);
- var results = [];
-
- var q = async.queue(function (task, callback) {
- callback(task.name === 'foo' ? new Error('fooError') : null);
- }, 2);
-
- q.drain = function() {
- test.deepEqual(results, ['bar', 'fooError']);
- test.done();
- };
-
- q.push({name: 'bar'}, function (err) {
- if(err) {
- results.push('barError');
- return;
- }
-
- results.push('bar');
- });
-
- q.push({name: 'foo'}, function (err) {
- if(err) {
- results.push('fooError');
- return;
- }
-
- results.push('foo');
- });
-},
-
- // The original queue implementation allowed the concurrency to be changed only
- // on the same event loop during which a task was added to the queue. This
- // test attempts to be a more robust test.
- // Start with a concurrency of 1. Wait until a leter event loop and change
- // the concurrency to 2. Wait again for a later loop then verify the concurrency.
- // Repeat that one more time by chaning the concurrency to 5.
- 'changing concurrency': function (test) {
- test.expect(3);
-
- var q = async.queue(function(task, callback){
- setTimeout(function(){
- callback();
- }, 100);
- }, 1);
-
- for(var i = 0; i < 50; i++){
- q.push('');
- }
-
- q.drain = function(){
- test.done();
- };
-
- setTimeout(function(){
- test.equal(q.concurrency, 1);
- q.concurrency = 2;
- setTimeout(function(){
- test.equal(q.running(), 2);
- q.concurrency = 5;
- setTimeout(function(){
- test.equal(q.running(), 5);
- }, 500);
- }, 500);
- }, 500);
-},
-
- 'push without callback': function (test) {
- test.expect(1);
- var call_order = [],
- delays = [160,80,240,80];
-
- // worker1: --1-4
- // worker2: -2---3
- // order of completion: 2,1,4,3
-
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- callback('error', 'arg');
- }, delays.splice(0,1)[0]);
- }, 2);
-
- q.push(1);
- q.push(2);
- q.push(3);
- q.push(4);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 2',
- 'process 1',
- 'process 4',
- 'process 3'
- ]);
- test.done();
- }, 800);
-},
-
- 'push with non-function': function (test) {
- test.expect(1);
- var q = async.queue(function () {}, 1);
- test.throws(function () {
- q.push({}, 1);
- });
- test.done();
-},
-
- 'unshift': function (test) {
- test.expect(1);
- var queue_order = [];
-
- var q = async.queue(function (task, callback) {
- queue_order.push(task);
- callback();
- }, 1);
-
- q.unshift(4);
- q.unshift(3);
- q.unshift(2);
- q.unshift(1);
-
- setTimeout(function () {
- test.same(queue_order, [ 1, 2, 3, 4 ]);
- test.done();
- }, 100);
-},
-
- 'too many callbacks': function (test) {
- test.expect(1);
- var q = async.queue(function (task, callback) {
- callback();
- test.throws(function() {
- callback();
- });
- test.done();
- }, 2);
-
- q.push(1);
-},
-
- 'bulk task': function (test) {
- test.expect(9);
- var call_order = [],
- delays = [160,80,240,80];
-
- // worker1: --1-4
- // worker2: -2---3
- // order of completion: 2,1,4,3
-
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- callback('error', task);
- }, delays.splice(0,1)[0]);
- }, 2);
-
- q.push( [1,2,3,4], function (err, arg) {
- test.equal(err, 'error');
- call_order.push('callback ' + arg);
- });
-
- test.equal(q.length(), 4);
- test.equal(q.concurrency, 2);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 2', 'callback 2',
- 'process 1', 'callback 1',
- 'process 4', 'callback 4',
- 'process 3', 'callback 3'
- ]);
- test.equal(q.concurrency, 2);
- test.equal(q.length(), 0);
- test.done();
- }, 800);
-},
-
- 'idle': function(test) {
- test.expect(7);
- var q = async.queue(function (task, callback) {
- // Queue is busy when workers are running
- test.equal(q.idle(), false);
- callback();
- }, 1);
-
- // Queue is idle before anything added
- test.equal(q.idle(), true);
-
- q.unshift(4);
- q.unshift(3);
- q.unshift(2);
- q.unshift(1);
-
- // Queue is busy when tasks added
- test.equal(q.idle(), false);
-
- q.drain = function() {
- // Queue is idle after drain
- test.equal(q.idle(), true);
- test.done();
- };
-},
-
- 'pause': function(test) {
- test.expect(3);
- var call_order = [],
- task_timeout = 100,
- pause_timeout = 300,
- resume_timeout = 500,
- tasks = [ 1, 2, 3, 4, 5, 6 ],
-
- elapsed = (function () {
- var start = (new Date()).valueOf();
- return function () {
- return Math.round(((new Date()).valueOf() - start) / 100) * 100;
- };
- })();
-
- var q = async.queue(function (task, callback) {
- call_order.push('process ' + task);
- call_order.push('timeout ' + elapsed());
- callback();
- });
-
- function pushTask () {
- var task = tasks.shift();
- if (!task) { return; }
- setTimeout(function () {
- q.push(task);
- pushTask();
- }, task_timeout);
- }
- pushTask();
-
- setTimeout(function () {
- q.pause();
- test.equal(q.paused, true);
- }, pause_timeout);
-
- setTimeout(function () {
- q.resume();
- test.equal(q.paused, false);
- }, resume_timeout);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 1', 'timeout 100',
- 'process 2', 'timeout 200',
- 'process 3', 'timeout 500',
- 'process 4', 'timeout 500',
- 'process 5', 'timeout 500',
- 'process 6', 'timeout 600'
- ]);
- test.done();
- }, 800);
-},
-
- 'pause in worker with concurrency': function(test) {
- test.expect(1);
- var call_order = [];
- var q = async.queue(function (task, callback) {
- if (task.isLongRunning) {
- q.pause();
- setTimeout(function () {
- call_order.push(task.id);
- q.resume();
- callback();
- }, 500);
- }
- else {
- call_order.push(task.id);
- callback();
- }
- }, 10);
-
- q.push({ id: 1, isLongRunning: true});
- q.push({ id: 2 });
- q.push({ id: 3 });
- q.push({ id: 4 });
- q.push({ id: 5 });
-
- setTimeout(function () {
- test.same(call_order, [1, 2, 3, 4, 5]);
- test.done();
- }, 1000);
- },
-
- 'pause with concurrency': function(test) {
- test.expect(4);
- var call_order = [],
- task_timeout = 100,
- pause_timeout = 50,
- resume_timeout = 300,
- tasks = [ 1, 2, 3, 4, 5, 6 ],
-
- elapsed = (function () {
- var start = (new Date()).valueOf();
- return function () {
- return Math.round(((new Date()).valueOf() - start) / 100) * 100;
- };
- })();
-
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- call_order.push('timeout ' + elapsed());
- callback();
- }, task_timeout);
- }, 2);
-
- q.push(tasks);
-
- setTimeout(function () {
- q.pause();
- test.equal(q.paused, true);
- }, pause_timeout);
-
- setTimeout(function () {
- q.resume();
- test.equal(q.paused, false);
- }, resume_timeout);
-
- setTimeout(function () {
- test.equal(q.running(), 2);
- }, resume_timeout + 10);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 1', 'timeout 100',
- 'process 2', 'timeout 100',
- 'process 3', 'timeout 400',
- 'process 4', 'timeout 400',
- 'process 5', 'timeout 500',
- 'process 6', 'timeout 500'
- ]);
- test.done();
- }, 800);
-},
-
- 'start paused': function (test) {
- test.expect(2);
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- callback();
- }, 40);
- }, 2);
- q.pause();
-
- q.push([1, 2, 3]);
-
- setTimeout(function () {
- q.resume();
- }, 5);
-
- setTimeout(function () {
- test.equal(q.tasks.length, 1);
- test.equal(q.running(), 2);
- q.resume();
- }, 15);
-
- q.drain = function () {
- test.done();
- };
-},
-
- 'kill': function (test) {
- test.expect(1);
- var q = async.queue(function (task, callback) {
- setTimeout(function () {
- test.ok(false, "Function should never be called");
- callback();
- }, 300);
- }, 1);
- q.drain = function() {
- test.ok(false, "Function should never be called");
- };
-
- q.push(0);
-
- q.kill();
-
- setTimeout(function() {
- test.equal(q.length(), 0);
- test.done();
- }, 600);
-},
-
- 'events': function(test) {
- test.expect(4);
- var calls = [];
- var q = async.queue(function(task, cb) {
- // nop
- calls.push('process ' + task);
- async.setImmediate(cb);
- }, 10);
- q.concurrency = 3;
-
- q.saturated = function() {
- test.ok(q.length() == 3, 'queue should be saturated now');
- calls.push('saturated');
- };
- q.empty = function() {
- test.ok(q.length() === 0, 'queue should be empty now');
- calls.push('empty');
- };
- q.drain = function() {
- test.ok(
- q.length() === 0 && q.running() === 0,
- 'queue should be empty now and no more workers should be running'
- );
- calls.push('drain');
- test.same(calls, [
- 'saturated',
- 'process foo',
- 'process bar',
- 'process zoo',
- 'foo cb',
- 'process poo',
- 'bar cb',
- 'empty',
- 'process moo',
- 'zoo cb',
- 'poo cb',
- 'moo cb',
- 'drain'
- ]);
- test.done();
- };
- q.push('foo', function () {calls.push('foo cb');});
- q.push('bar', function () {calls.push('bar cb');});
- q.push('zoo', function () {calls.push('zoo cb');});
- q.push('poo', function () {calls.push('poo cb');});
- q.push('moo', function () {calls.push('moo cb');});
-},
-
- 'empty': function(test) {
- test.expect(2);
- var calls = [];
- var q = async.queue(function(task, cb) {
- // nop
- calls.push('process ' + task);
- async.setImmediate(cb);
- }, 3);
-
- q.drain = function() {
- test.ok(
- q.length() === 0 && q.running() === 0,
- 'queue should be empty now and no more workers should be running'
- );
- calls.push('drain');
- test.same(calls, [
- 'drain'
- ]);
- test.done();
- };
- q.push([]);
-},
-
- 'saturated': function (test) {
- test.expect(1);
- var saturatedCalled = false;
- var q = async.queue(function(task, cb) {
- async.setImmediate(cb);
- }, 2);
-
- q.saturated = function () {
- saturatedCalled = true;
- };
- q.drain = function () {
- test.ok(saturatedCalled, "saturated not called");
- test.done();
- };
-
- setTimeout(function () {
- q.push(['foo', 'bar', 'baz', 'moo']);
- }, 10);
-},
-
- 'started': function(test) {
- test.expect(2);
-
- var q = async.queue(function(task, cb) {
- cb(null, task);
- });
-
- test.equal(q.started, false);
- q.push([]);
- test.equal(q.started, true);
- test.done();
-}
-
-};
-
-
-exports['priorityQueue'] = {
-
- 'priorityQueue': function (test) {
- test.expect(17);
- var call_order = [];
-
- // order of completion: 2,1,4,3
-
- var q = async.priorityQueue(function (task, callback) {
- call_order.push('process ' + task);
- callback('error', 'arg');
- }, 1);
-
- q.push(1, 1.4, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 2);
- call_order.push('callback ' + 1);
- });
- q.push(2, 0.2, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 3);
- call_order.push('callback ' + 2);
- });
- q.push(3, 3.8, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 3);
- });
- q.push(4, 2.9, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 1);
- call_order.push('callback ' + 4);
- });
- test.equal(q.length(), 4);
- test.equal(q.concurrency, 1);
-
- q.drain = function () {
- test.same(call_order, [
- 'process 2', 'callback 2',
- 'process 1', 'callback 1',
- 'process 4', 'callback 4',
- 'process 3', 'callback 3'
- ]);
- test.equal(q.concurrency, 1);
- test.equal(q.length(), 0);
- test.done();
- };
-},
-
- 'concurrency': function (test) {
- test.expect(17);
- var call_order = [],
- delays = [160,80,240,80];
-
- // worker1: --2-3
- // worker2: -1---4
- // order of completion: 1,2,3,4
-
- var q = async.priorityQueue(function (task, callback) {
- setTimeout(function () {
- call_order.push('process ' + task);
- callback('error', 'arg');
- }, delays.splice(0,1)[0]);
- }, 2);
-
- q.push(1, 1.4, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 2);
- call_order.push('callback ' + 1);
- });
- q.push(2, 0.2, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 1);
- call_order.push('callback ' + 2);
- });
- q.push(3, 3.8, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 3);
- });
- q.push(4, 2.9, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(q.length(), 0);
- call_order.push('callback ' + 4);
- });
- test.equal(q.length(), 4);
- test.equal(q.concurrency, 2);
-
- q.drain = function () {
- test.same(call_order, [
- 'process 1', 'callback 1',
- 'process 2', 'callback 2',
- 'process 3', 'callback 3',
- 'process 4', 'callback 4'
- ]);
- test.equal(q.concurrency, 2);
- test.equal(q.length(), 0);
- test.done();
- };
-}
-
-};
-
-
-exports['cargo'] = {
-
- 'cargo': function (test) {
- test.expect(19);
- var call_order = [],
- delays = [160, 160, 80];
-
- // worker: --12--34--5-
- // order of completion: 1,2,3,4,5
-
- var c = async.cargo(function (tasks, callback) {
- setTimeout(function () {
- call_order.push('process ' + tasks.join(' '));
- callback('error', 'arg');
- }, delays.shift());
- }, 2);
-
- c.push(1, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(c.length(), 3);
- call_order.push('callback ' + 1);
- });
- c.push(2, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(c.length(), 3);
- call_order.push('callback ' + 2);
- });
-
- test.equal(c.length(), 2);
-
- // async push
- setTimeout(function () {
- c.push(3, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(c.length(), 1);
- call_order.push('callback ' + 3);
- });
- }, 60);
- setTimeout(function () {
- c.push(4, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(c.length(), 1);
- call_order.push('callback ' + 4);
- });
- test.equal(c.length(), 2);
- c.push(5, function (err, arg) {
- test.equal(err, 'error');
- test.equal(arg, 'arg');
- test.equal(c.length(), 0);
- call_order.push('callback ' + 5);
- });
- }, 120);
-
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 1 2', 'callback 1', 'callback 2',
- 'process 3 4', 'callback 3', 'callback 4',
- 'process 5' , 'callback 5'
- ]);
- test.equal(c.length(), 0);
- test.done();
- }, 800);
-},
-
- 'without callback': function (test) {
- test.expect(1);
- var call_order = [],
- delays = [160,80,240,80];
-
- // worker: --1-2---34-5-
- // order of completion: 1,2,3,4,5
-
- var c = async.cargo(function (tasks, callback) {
- setTimeout(function () {
- call_order.push('process ' + tasks.join(' '));
- callback('error', 'arg');
- }, delays.shift());
- }, 2);
-
- c.push(1);
-
- setTimeout(function () {
- c.push(2);
- }, 120);
- setTimeout(function () {
- c.push(3);
- c.push(4);
- c.push(5);
- }, 180);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 1',
- 'process 2',
- 'process 3 4',
- 'process 5'
- ]);
- test.done();
- }, 800);
-},
-
- 'bulk task': function (test) {
- test.expect(7);
- var call_order = [],
- delays = [120,40];
-
- // worker: -123-4-
- // order of completion: 1,2,3,4
-
- var c = async.cargo(function (tasks, callback) {
- setTimeout(function () {
- call_order.push('process ' + tasks.join(' '));
- callback('error', tasks.join(' '));
- }, delays.shift());
- }, 3);
-
- c.push( [1,2,3,4], function (err, arg) {
- test.equal(err, 'error');
- call_order.push('callback ' + arg);
- });
-
- test.equal(c.length(), 4);
-
- setTimeout(function () {
- test.same(call_order, [
- 'process 1 2 3', 'callback 1 2 3',
- 'callback 1 2 3', 'callback 1 2 3',
- 'process 4', 'callback 4',
- ]);
- test.equal(c.length(), 0);
- test.done();
- }, 800);
-},
-
- 'drain once': function (test) {
- test.expect(1);
-
- var c = async.cargo(function (tasks, callback) {
- callback();
- }, 3);
-
- var drainCounter = 0;
- c.drain = function () {
- drainCounter++;
- };
-
- for(var i = 0; i < 10; i++){
- c.push(i);
- }
-
- setTimeout(function(){
- test.equal(drainCounter, 1);
- test.done();
- }, 500);
-},
-
- 'drain twice': function (test) {
- test.expect(1);
-
- var c = async.cargo(function (tasks, callback) {
- callback();
- }, 3);
-
- var loadCargo = function(){
- for(var i = 0; i < 10; i++){
- c.push(i);
- }
- };
-
- var drainCounter = 0;
- c.drain = function () {
- drainCounter++;
- };
-
- loadCargo();
- setTimeout(loadCargo, 500);
-
- setTimeout(function(){
- test.equal(drainCounter, 2);
- test.done();
- }, 1000);
-},
-
- 'events': function(test) {
- test.expect(4);
- var calls = [];
- var q = async.cargo(function(task, cb) {
- // nop
- calls.push('process ' + task);
- async.setImmediate(cb);
- }, 1);
- q.concurrency = 3;
-
- q.saturated = function() {
- test.ok(q.length() == 3, 'cargo should be saturated now');
- calls.push('saturated');
- };
- q.empty = function() {
- test.ok(q.length() === 0, 'cargo should be empty now');
- calls.push('empty');
- };
- q.drain = function() {
- test.ok(
- q.length() === 0 && q.running() === 0,
- 'cargo should be empty now and no more workers should be running'
- );
- calls.push('drain');
- test.same(calls, [
- 'saturated',
- 'process foo',
- 'process bar',
- 'process zoo',
- 'foo cb',
- 'process poo',
- 'bar cb',
- 'empty',
- 'process moo',
- 'zoo cb',
- 'poo cb',
- 'moo cb',
- 'drain'
- ]);
- test.done();
- };
- q.push('foo', function () {calls.push('foo cb');});
- q.push('bar', function () {calls.push('bar cb');});
- q.push('zoo', function () {calls.push('zoo cb');});
- q.push('poo', function () {calls.push('poo cb');});
- q.push('moo', function () {calls.push('moo cb');});
-},
-
- 'expose payload': function (test) {
- test.expect(5);
- var called_once = false;
- var cargo= async.cargo(function(tasks, cb) {
- if (!called_once) {
- test.equal(cargo.payload, 1);
- test.ok(tasks.length === 1, 'should start with payload = 1');
- } else {
- test.equal(cargo.payload, 2);
- test.ok(tasks.length === 2, 'next call shold have payload = 2');
- }
- called_once = true;
- setTimeout(cb, 25);
- }, 1);
-
- cargo.drain = function () {
- test.done();
- };
-
- test.equals(cargo.payload, 1);
-
- cargo.push([1, 2, 3]);
-
- setTimeout(function () {
- cargo.payload = 2;
- }, 15);
-}
-
-};
-
-
exports['memoize'] = {
@@ -3825,3 +2768,49 @@ exports['asyncify'] = {
return promises;
}, {})
};
+
+exports['timeout'] = function (test) {
+ test.expect(3);
+
+ async.series([
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I didn\'t time out');
+ }, 50);
+ }, 200),
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I will time out');
+ }, 300);
+ }, 150)
+ ],
+ function(err, results) {
+ test.ok(err.message === 'Callback function timed out.');
+ test.ok(err.code === 'ETIMEDOUT');
+ test.ok(results[0] === 'I didn\'t time out');
+ test.done();
+ });
+};
+
+exports['timeout with parallel'] = function (test) {
+ test.expect(3);
+
+ async.parallel([
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I didn\'t time out');
+ }, 50);
+ }, 200),
+ async.timeout(function asyncFn(callback) {
+ setTimeout(function() {
+ callback(null, 'I will time out');
+ }, 300);
+ }, 150)
+ ],
+ function(err, results) {
+ test.ok(err.message === 'Callback function timed out.');
+ test.ok(err.code === 'ETIMEDOUT');
+ test.ok(results[0] === 'I didn\'t time out');
+ test.done();
+ });
+};