From 4a4247479ec88ec14a6a5313daee3f558c36a63d Mon Sep 17 00:00:00 2001 From: Benjamin Coe Date: Sat, 23 May 2015 15:33:41 -0700 Subject: [PATCH 1/2] added test coverage with coveralls and nyc --- .gitignore | 2 + .travis.yml | 1 + README.md | 160 +++++++++++++++++++++++++-------------------------- package.json | 6 +- 4 files changed, 88 insertions(+), 81 deletions(-) diff --git a/.gitignore b/.gitignore index 291d97eb0..82b59efd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules dist perf/versions +nyc_output +coverage diff --git a/.travis.yml b/.travis.yml index 6064ca092..eb35ea044 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,4 @@ node_js: - "0.10" - "0.12" - "iojs" +after_success: npm run coveralls diff --git a/README.md b/README.md index 6775ad541..2257d9bd9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![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/bcoe/async/badge.svg?branch=)](https://coveralls.io/r/bcoe/async?branch=) Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for @@ -62,7 +62,7 @@ a method of another library isn't working as an iterator, study this example: // Here is a simple object with an (unnecessarily roundabout) squaring method var AsyncSquaringLibrary = { squareExponent: 2, - square: function(number, callback){ + square: function(number, callback){ var result = Math.pow(number, this.squareExponent); setTimeout(function(){ callback(null, result); @@ -80,7 +80,7 @@ async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ // result is [1, 4, 9] // With the help of bind we can attach a context to the iterator before - // passing it to async. Now the square function will be executed in its + // passing it to async. Now the square function will be executed in its // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` // will be as expected. }); @@ -94,7 +94,7 @@ Alternatively, you can install using Node Package Manager (`npm`): npm install async -As well as using Bower: +As well as using Bower: bower install async @@ -102,7 +102,7 @@ __Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async ## In the Browser -So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. +So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: @@ -197,8 +197,8 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A function to apply to each item in `arr`. - The iterator is passed a `callback(err)` which must be called once it has - completed. If no error has occurred, the `callback` should be run without + The iterator 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 to the iterator. If you need the index, use [`forEachOf`](#forEachOf). * `callback(err)` - A callback which is called when all `iterator` functions @@ -217,13 +217,13 @@ async.each(openFiles, saveFile, function(err){ ``` ```js -// assuming openFiles is an array of file names +// assuming openFiles is an array of file names async.each(openFiles, function(file, callback) { - + // Perform operation on file here. console.log('Processing file ' + file); - + if( file.length > 32 ) { console.log('This file name is too long'); callback('File name too long'); @@ -251,7 +251,7 @@ async.each(openFiles, function(file, callback) { ### eachSeries(arr, iterator, callback) The same as [`each`](#each), only `iterator` is applied to each item in `arr` in -series. The next `iterator` is only called once the current one has completed. +series. The next `iterator` is only called once the current one has completed. This means the `iterator` functions will complete in order. @@ -261,10 +261,10 @@ This means the `iterator` functions will complete in order. ### eachLimit(arr, limit, iterator, callback) -The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously +The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously running at any time. -Note that the items in `arr` are not processed in batches, so there is no guarantee that +Note that the items in `arr` are not processed in batches, so there is no guarantee that the first `limit` `iterator` functions will complete before any others are started. __Arguments__ @@ -272,8 +272,8 @@ __Arguments__ * `arr` - An array to iterate over. * `limit` - The maximum number of `iterator`s to run at any time. * `iterator(item, callback)` - A function to apply to each item in `arr`. - The iterator is passed a `callback(err)` which must be called once it has - completed. If no error has occurred, the callback should be run without + The iterator 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. * `callback(err)` - A callback which is called when all `iterator` functions have finished, or an error occurs. @@ -301,8 +301,8 @@ Like `each`, except that it iterates over objects, and passes the key as the sec __Arguments__ * `obj` - An object or array to iterate over. -* `iterator(item, key, callback)` - A function to apply to each item in `obj`. -The `key` is the item's key, or index in the case of an array. The iterator is +* `iterator(item, key, callback)` - A function to apply to each item in `obj`. +The `key` is the item's key, or index in the case of an array. The iterator 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. @@ -357,19 +357,19 @@ Like [`forEachOf`](#forEachOf), except the number of `iterator`s running at a gi Produces a new array of values by mapping each value in `arr` through the `iterator` function. The `iterator` is called with an item from `arr` 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 `iterator` passes an error to its +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` 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 `iterator` to each item in parallel, -there is no guarantee that the `iterator` functions will complete in order. +there is no guarantee that the `iterator` functions will complete in order. However, the results array will be in the same order as the original `arr`. __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A function to apply to each item in `arr`. - The iterator is passed a `callback(err, transformed)` which must be called once + The iterator 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)` - A callback which is called when all `iterator` functions have finished, or an error occurs. Results is an array of the @@ -389,7 +389,7 @@ async.map(['file1','file2','file3'], fs.stat, function(err, results){ ### mapSeries(arr, iterator, callback) The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in -series. The next `iterator` is only called once the current one has completed. +series. The next `iterator` is only called once the current one has completed. The results array will be in the same order as the original. @@ -398,10 +398,10 @@ The results array will be in the same order as the original. ### mapLimit(arr, limit, iterator, callback) -The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously +The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously running at any time. -Note that the items are not processed in batches, so there is no guarantee that +Note that the items are not processed in batches, so there is no guarantee that the first `limit` `iterator` functions will complete before any others are started. __Arguments__ @@ -409,7 +409,7 @@ __Arguments__ * `arr` - An array to iterate over. * `limit` - The maximum number of `iterator`s to run at any time. * `iterator(item, callback)` - A function to apply to each item in `arr`. - The iterator is passed a `callback(err, transformed)` which must be called once + The iterator 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)` - A callback which is called when all `iterator` calls have finished, or an error occurs. The result is an array of the @@ -442,7 +442,7 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A truth test to apply to each item in `arr`. - The `iterator` is passed a `callback(truthValue)`, which must be called with a + The `iterator` is passed a `callback(truthValue)`, which must be called with a boolean argument once it has completed. * `callback(results)` - A callback which is called after all the `iterator` functions have finished. @@ -464,7 +464,7 @@ async.filter(['file1','file2','file3'], fs.exists, function(results){ __Alias:__ `selectSeries` The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in -series. The next `iterator` is only called once the current one has completed. +series. The next `iterator` is only called once the current one has completed. The results array will be in the same order as the original. --------------------------------------- @@ -491,12 +491,12 @@ in series. __Aliases:__ `inject`, `foldl` Reduces `arr` into a single value using an async `iterator` to return -each successive step. `memo` is the initial state of the reduction. -This function only operates in series. +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. -For performance reasons, it may make sense to split a call to this function into -a parallel map, and then use the normal `Array.prototype.reduce` on the results. -This function is for situations where each step in the reduction needs to be async; +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; if you can get the data before reducing it, then it's probably a good idea to do so. __Arguments__ @@ -505,9 +505,9 @@ __Arguments__ * `memo` - The initial state of the reduction. * `iterator(memo, item, callback)` - A function applied to each item in the array to produce the next step in the reduction. The `iterator` is passed a - `callback(err, reduction)` which accepts an optional error as its first - argument, and the state of the reduction as the second. If an error is - passed to the callback, the reduction is stopped and the main `callback` is + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is immediately called with the error. * `callback(err, result)` - A callback which is called after all the `iterator` functions have finished. Result is the reduced value. @@ -551,7 +551,7 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A truth test to apply to each item in `arr`. - The iterator is passed a `callback(truthValue)` which must be called with a + The iterator is passed a `callback(truthValue)` which must be called with a boolean argument once it has completed. **Note: this callback does not take an error as its first argument.** * `callback(result)` - A callback which is called as soon as any iterator returns `true`, or after all the `iterator` functions have finished. Result will be @@ -644,7 +644,7 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A truth test to apply to each item in the array - in parallel. The iterator is passed a `callback(truthValue)`` which must be + in parallel. The iterator is passed a `callback(truthValue)`` which must be called with a boolean argument once it has completed. * `callback(result)` - A callback which is called as soon as any iterator returns `true`, or after all the iterator functions have finished. Result will be @@ -675,7 +675,7 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A truth test to apply to each item in the array - in parallel. The iterator is passed a `callback(truthValue)` which must be + in parallel. The iterator is passed a `callback(truthValue)` which must be called with a boolean argument once it has completed. * `callback(result)` - A callback which is called after all the `iterator` functions have finished. Result will be either `true` or `false` depending on @@ -705,7 +705,7 @@ __Arguments__ * `arr` - An array to iterate over. * `iterator(item, callback)` - A function to apply to each item in `arr`. - The iterator is passed a `callback(err, results)` which must be called once it + The iterator 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)` - A callback which is called after all the `iterator` functions have finished, or an error occurs. Results is an array containing @@ -734,7 +734,7 @@ Same as [`concat`](#concat), but executes in series instead of parallel. Run the functions in the `tasks` array 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. +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. It is also possible to use an object instead of an array. Each property will be @@ -743,13 +743,13 @@ instead of an array. This can be a more readable way of handling results from [`series`](#series). **Note** that while many implementations preserve the order of object properties, the -[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) explicitly states that > The mechanics and order of enumerating the properties is not specified. So if you rely on the order in which your series of functions are executed, and want -this to work on all platforms, consider using an array. +this to work on all platforms, consider using an array. __Arguments__ @@ -757,7 +757,7 @@ __Arguments__ 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 - have completed. This function gets a results array (or object) containing all + have completed. This function gets a results array (or object) containing all the result arguments passed to the `task` callbacks. __Example__ @@ -816,11 +816,11 @@ 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 - a `callback(err, result)` which it must call on completion with an error `err` +* `tasks` - An array or object 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 - have completed. This function gets a results array (or object) containing all + have completed. This function gets a results array (or object) containing all the result arguments passed to the task callbacks. __Example__ @@ -868,20 +868,20 @@ function(err, results) { ### parallelLimit(tasks, limit, [callback]) -The same as [`parallel`](#parallel), only `tasks` are executed in parallel +The same as [`parallel`](#parallel), only `tasks` are executed in parallel with a maximum of `limit` tasks executing at any time. -Note that the `tasks` are not executed in batches, so there is no guarantee that +Note that the `tasks` are not executed in batches, so there is no guarantee that the first `limit` tasks will complete before any others are started. __Arguments__ -* `tasks` - An array or object containing functions to run, each function is passed +* `tasks` - An array or object 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. * `limit` - The maximum number of `tasks` to run at any time. * `callback(err, results)` - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all + have completed. This function gets a results array (or object) containing all the result arguments passed to the `task` callbacks. --------------------------------------- @@ -896,7 +896,7 @@ __Arguments__ * `test()` - synchronous truth test to perform before each execution of `fn`. * `fn(callback)` - A function which is called each time `test` passes. The function is - passed a `callback(err)`, which must be called once it has completed with an + passed a `callback(err)`, which must be called once it has completed with an optional `err` argument. * `callback(err)` - A callback which is called after the test fails and repeated execution of `fn` has stopped. @@ -923,8 +923,8 @@ async.whilst( ### doWhilst(fn, test, callback) -The post-check version of [`whilst`](#whilst). To reflect the difference in -the order of operations, the arguments `test` and `fn` are switched. +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. @@ -981,9 +981,9 @@ the error. __Arguments__ -* `tasks` - An array of functions to run, each function is passed a +* `tasks` - An array of functions to run, each function is passed a `callback(err, result1, result2, ...)` it must call on completion. The first - argument is an error (which can be `null`) and any further arguments will be + argument is an error (which can be `null`) and any further arguments will be passed as arguments in order to the next task. * `callback(err, [results])` - An optional callback to run once all the functions have completed. This will be passed the results of the last task's callback. @@ -1006,7 +1006,7 @@ async.waterfall([ callback(null, 'done'); } ], function (err, result) { - // result now equals 'done' + // result now equals 'done' }); ``` @@ -1068,7 +1068,7 @@ __Example__ ```js // Requires lodash (or underscore), express3 and dresende's orm2. // Part of an app, that fetches cats of the logged user. -// This example uses `seq` function to avoid overnesting and error +// This example uses `seq` function to avoid overnesting and error // handling clutter. app.get('/cats', function(request, response) { var User = request.models.User; @@ -1092,7 +1092,7 @@ app.get('/cats', function(request, response) { ### applyEach(fns, args..., callback) -Applies the provided arguments to each function in the array, calling +Applies the provided arguments to each function in the array, calling `callback` after all functions have completed. If you only provide the first argument, then it will return a function which lets you pass in the arguments as if it were a single function call. @@ -1132,13 +1132,13 @@ The same as [`applyEach`](#applyEach) only the functions are applied in series. Creates a `queue` object with the specified `concurrency`. Tasks added to the `queue` are processed in parallel (up to the `concurrency` limit). If all -`worker`s are in progress, the task is queued until one becomes available. +`worker`s are in progress, the task is queued until one becomes available. Once a `worker` completes a `task`, that `task`'s callback is called. __Arguments__ * `worker(task, callback)` - An asynchronous function for processing a queued - task, which must call its `callback(err)` argument when finished, with an + task, which must call its `callback(err)` argument when finished, with an optional `error` as an argument. If you want to handle errors from an individual task, pass a callback to `q.push()`. * `concurrency` - An `integer` for determining how many `worker` functions should be run in parallel. If omitted, the concurrency defaults to `1`. If the concurrency is `0`, an error is thrown. @@ -1155,11 +1155,11 @@ methods: * `concurrency` - an integer for determining how many `worker` functions should be run in parallel. This property can be changed after a `queue` is created to alter the concurrency on-the-fly. -* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once 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, +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, 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`. @@ -1236,7 +1236,7 @@ when the worker is finished. __Arguments__ * `worker(tasks, callback)` - An asynchronous function for processing an array of - queued tasks, which must call its `callback(err)` argument when finished, with + queued tasks, which must call its `callback(err)` argument when finished, with an optional `err` argument. * `payload` - An optional `integer` for determining how many tasks should be processed per round; if omitted, the default is unlimited. @@ -1251,7 +1251,7 @@ methods: process per round. This property can be changed after a `cargo` is created to alter the payload on-the-fly. * `push(task, [callback])` - Adds `task` to the `queue`. The callback is called - once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` can be submitted. The respective callback is used for every task in the list. * `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`. @@ -1288,18 +1288,18 @@ cargo.push({name: 'baz'}, function (err) { ### auto(tasks, [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. +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. -If any of the functions pass an error to their callback, it will not -complete (so any other functions depending on it will not run), and the main -`callback` is immediately called with the error. Functions also receive an +If any of the functions pass an error to their callback, it will not +complete (so any other functions depending on it will not run), and the main +`callback` is immediately called with the error. Functions also receive an object containing the results of functions which have completed so far. -Note, all functions are called with a `results` object as a second argument, +Note, all functions are called with a `results` object as a second argument, so it is unsafe to pass functions in the `tasks` object which cannot handle the -extra argument. +extra argument. For example, this snippet of code: @@ -1316,7 +1316,7 @@ argument, which will fail: fs.readFile('data.txt', 'utf-8', cb, {}); ``` -Instead, wrap the call to `readFile` in a function which does not forward the +Instead, wrap the call to `readFile` in a function which does not forward the `results` object: ```js @@ -1333,13 +1333,13 @@ __Arguments__ requirements, with the function itself the last item in the array. 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 function receives two arguments: (1) a `callback(err, result)` which must be - called when finished, passing an `error` (which can be `null`) and the result of + The function receives two arguments: (1) 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, and (2) a `results` object, containing the results of the previously executed functions. * `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. Results are always returned; however, if + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if an error occurs, no further `tasks` will be performed, and the results object will only contain partial results. @@ -1430,7 +1430,7 @@ __Arguments__ * `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5. * `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` - which must be called when finished, passing `err` (which can be `null`) and the `result` of + which must be called when finished, passing `err` (which can be `null`) and the `result` of the function's execution, and (2) a `results` object, containing the results of the previously executed functions (if nested inside another control flow). * `callback(err, results)` - An optional callback which is called when the @@ -1499,7 +1499,7 @@ node> nextfn(); ### apply(function, arguments..) -Creates a continuation function with some arguments already applied. +Creates a continuation function with some arguments already applied. Useful as a shorthand when combined with other control flow functions. Any arguments passed to the returned function are added to the arguments originally passed @@ -1607,7 +1607,7 @@ async.times(5, function(n, next){ ### timesSeries(n, iterator, callback) The same as [`times`](#times), only the iterator is applied to each item in `arr` in -series. The next `iterator` is only called once the current one has completed. +series. The next `iterator` is only called once the current one has completed. The results array will be in the same order as the original. diff --git a/package.json b/package.json index 6e7282be7..601f50f5f 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,12 @@ "license": "MIT", "devDependencies": { "benchmark": "bestiejs/benchmark.js", + "coveralls": "^2.11.2", "jshint": "~2.7.0", "lodash": ">=2.4.1", "mkdirp": "~0.5.1", "nodeunit": ">0.0.0", + "nyc": "^2.1.0", "uglify-js": "1.2.x", "yargs": "~3.9.1" }, @@ -40,7 +42,9 @@ }, "scripts": { "test": "npm run-script lint && nodeunit test/test-async.js", - "lint": "jshint lib/*.js test/*.js perf/*.js" + "lint": "jshint lib/*.js test/*.js perf/*.js", + "coverage": "nyc npm test && nyc report", + "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls" }, "spm": { "main": "lib/async.js" From d5e669f64cb16eeb46f988885d94ccd88ab4dd4d Mon Sep 17 00:00:00 2001 From: Benjamin Coe Date: Sat, 23 May 2015 16:41:11 -0700 Subject: [PATCH 2/2] switch to caolan from bcoe --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2257d9bd9..d09f9f0b7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![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/bcoe/async/badge.svg?branch=)](https://coveralls.io/r/bcoe/async?branch=) +[![Coverage Status](https://coveralls.io/repos/caolan/async/badge.svg?branch=)](https://coveralls.io/r/caolan/async?branch=) Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for