asynccond
Advanced tools
Comparing version 1.0.0 to 1.1.0
84
index.js
@@ -13,4 +13,10 @@ /** | ||
M = {}, // define the module | ||
moduleName = 'asyncexit'; // the name of the module | ||
moduleName = 'asynccond'; // the name of the module | ||
var _isArray = Array.isArray || function (obj) { | ||
return _toString.call(obj) === '[object Array]'; | ||
}; | ||
function noop (){}; | ||
function _toArray(obj) { | ||
@@ -22,4 +28,6 @@ var res = { | ||
for (var key in obj) { | ||
res.keys.push(key); | ||
res.vals.push(obj[key]); | ||
if (obj.hasOwnProperty(key)) { | ||
res.keys.push(key); | ||
res.vals.push(obj[key]); | ||
} | ||
} | ||
@@ -44,2 +52,62 @@ return res; | ||
/** | ||
* Applies the function `iterator` to each item in `arr` in series. | ||
* The `iterator` is called with an item from `arr`, and a callback | ||
* when it has finished. If the `iterator` passes an error to its | ||
* callback, the main `callback` is immediately called with the error. | ||
* | ||
* If a condition is applied on the internal callback of `iterator`, | ||
* it pre-exits the series. | ||
* | ||
* #### Example | ||
* | ||
* ````js | ||
* eachSeries( | ||
* [ 1, 2, 3, 4, 5 ], | ||
* // iterator | ||
* function (data, cb) { | ||
* cb(null, data * 2, (data * 2 > 5)); // exits if condition is met | ||
* }, | ||
* // callback | ||
* function(err, data){ | ||
* //> data = [ 2, 4, 6 ]); | ||
* } | ||
* ); | ||
* ```` | ||
* | ||
* | ||
* @param {Array} arr - array of items which are passed to `iterator` | ||
* @param {Function} iterator - `function(item, cb)` `cb` needs to be called inside `iterator` | ||
* @param {Function} [callback] - is of type `function(err, result)` and called after running the series | ||
*/ | ||
function eachSeries(arr, iterator, callback) { | ||
var i = 0, | ||
results = []; | ||
callback = callback || noop; | ||
function cb(err, res, exit){ | ||
results.push(res); | ||
if (err || exit) { | ||
return callback(err, results); | ||
} | ||
else { | ||
run(); | ||
} | ||
} | ||
function run() { | ||
var a = arr[i++]; | ||
if (a) { | ||
iterator(a, cb); | ||
} | ||
else { | ||
return callback(null, results); | ||
} | ||
} | ||
run(); | ||
} | ||
M.eachSeries = eachSeries; | ||
/** | ||
* Run the functions in the `tasks` array in series, each one running | ||
@@ -83,3 +151,3 @@ * once the previous function has completed. If any functions in the | ||
* @param {Array|Object} tasks - the async functions to run in series | ||
* @param {Function} callback - is of type `function(err, result)` and called after running the series | ||
* @param {Function} [callback] - is of type `function(err, result)` and called after running the series | ||
*/ | ||
@@ -91,3 +159,5 @@ function series(tasks, callback) { | ||
if (!Array.isArray(tasks) && typeof(tasks) === 'object') { | ||
callback = callback || noop; | ||
if (!_isArray(tasks) && typeof(tasks) === 'object') { | ||
keys = _toArray(tasks); | ||
@@ -175,3 +245,3 @@ tasks = keys.vals; | ||
if (tasks.length === 1) { | ||
if (Array.isArray(tasks[0])) { | ||
if (_isArray(tasks[0])) { | ||
tasks = tasks[0]; | ||
@@ -212,3 +282,3 @@ } | ||
return function(data, _callback) { | ||
callback = _callback; | ||
callback = _callback || noop; | ||
i = 0; | ||
@@ -215,0 +285,0 @@ run(null, data); |
{ | ||
"name": "asynccond", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "async series with conditional exit", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -8,7 +8,9 @@ # asynccond | ||
Execute async functions in series with the ability to conditionally pre-exit the sequence. | ||
Async series functions with the ability to conditionally pre-exit the sequence. | ||
`seq` furthermore allows to trap errors within the sequence. | ||
The functions provided are backwards compatible with [async][]. | ||
## Table of Contents | ||
@@ -19,2 +21,3 @@ | ||
* [Description](#description) | ||
* [eachSeries(arr, iterator, callback)](#eachseriesarr-iterator-callback) | ||
* [series(tasks, callback)](#seriestasks-callback) | ||
@@ -30,2 +33,38 @@ * [seq(tasks)](#seqtasks) | ||
### eachSeries(arr, iterator, callback) | ||
Applies the function `iterator` to each item in `arr` in series. | ||
The `iterator` is called with an item from `arr`, and a callback | ||
when it has finished. If the `iterator` passes an error to its | ||
callback, the main `callback` is immediately called with the error. | ||
If a condition is applied on the internal callback of `iterator`, | ||
it pre-exits the series. | ||
#### Example | ||
````js | ||
eachSeries( | ||
[ 1, 2, 3, 4, 5 ], | ||
// iterator | ||
function (data, cb) { | ||
cb(null, data * 2, (data * 2 > 5)); // exits if condition is met | ||
}, | ||
// callback | ||
function(err, data){ | ||
//> data = [ 2, 4, 6 ]); | ||
} | ||
); | ||
```` | ||
**Parameters** | ||
**arr**: `Array`, array of items which are passed to `iterator` | ||
**iterator**: `function`, `function(item, cb)` `cb` needs to be called inside `iterator` | ||
**callback**: `function`, is of type `function(err, result)` and called after running the series | ||
### series(tasks, callback) | ||
@@ -145,2 +184,3 @@ | ||
* [async][async] | ||
* [LICENSE][LICENSE] | ||
@@ -151,5 +191,5 @@ | ||
[LICENSE]: ./LICENSE | ||
[async]: https://github.com/caolan/async | ||
@@ -9,6 +9,7 @@ /** | ||
var assert = require('assert'); | ||
var seq = require('../index.js').seq; | ||
var seq = require('../index.js').seq; | ||
var series = require('../index.js').series; | ||
var eachSeries = require('../index.js').eachSeries; | ||
/* globals describe, it */ ///< used for jshint | ||
/* globals describe, it */ | ||
@@ -31,2 +32,58 @@ // test helper | ||
describe('#eachSeries', function(){ | ||
it('can process an async function in series ', function(done){ | ||
eachSeries([ 1, 2, 3, 4 ], | ||
function (data, cb) { | ||
process.nextTick(function(){ | ||
cb(null, data * 2); | ||
}); | ||
}, | ||
function(err, data){ | ||
assert.ok(!err, ''+err); | ||
assert.deepEqual(data, [ 2, 4, 6, 8 ]); | ||
done(); | ||
} | ||
); | ||
}); | ||
it('can exit on err', function(done){ | ||
var i = 0; | ||
eachSeries([ 1, 2, 3, 4 ], | ||
function (data, cb) { | ||
var err; | ||
if (++i >= 2) { | ||
err = 'err'; | ||
} | ||
process.nextTick(function(){ | ||
cb(err, data * 2); | ||
}); | ||
}, | ||
function(err, data){ | ||
assert.ok(err, ''+err); | ||
assert.deepEqual(data, [ 2, 4 ]); | ||
done(); | ||
} | ||
); | ||
}); | ||
it('can pre-exit on condition', function(done){ | ||
eachSeries([ 1, 2, 3, 4 ], | ||
function (data, cb) { | ||
process.nextTick(function(){ | ||
cb(null, data * 2, (data * 2 > 5)); | ||
}); | ||
}, | ||
function(err, data){ | ||
assert.ok(!err, ''+err); | ||
assert.deepEqual(data, [ 2, 4, 6 ]); | ||
done(); | ||
} | ||
); | ||
}); | ||
}); | ||
describe('#series', function(){ | ||
@@ -97,3 +154,3 @@ | ||
it('can process async function in series with pre-exit', function(done){ | ||
it('can pre-exit on condition', function(done){ | ||
var data = 0 | ||
@@ -228,3 +285,3 @@ | ||
it('can pre-exit', function(done){ | ||
it('can pre-exit on condition', function(done){ | ||
seq( | ||
@@ -231,0 +288,0 @@ step, |
Sorry, the diff of this file is not supported yet
19015
532
191