Skip to content

Commit

Permalink
added forEach, map, reduce, filter, some, and every functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Caolan McMahon committed May 26, 2010
1 parent d7d0349 commit 950183f
Show file tree
Hide file tree
Showing 2 changed files with 351 additions and 0 deletions.
132 changes: 132 additions & 0 deletions lib/async.js
Expand Up @@ -121,3 +121,135 @@ exports.iterator = function(tasks){
};
return makeCallback(0);
};

exports.forEach = function(arr, iterator, callback){
var completed = 0;
arr.forEach(function(x){
iterator(x, function(err){
if(err){
callback(err);
callback = function(){};
}
else {
completed++;
if(completed == arr.length) callback();
}
});
});
};

exports.forEachSeries = function(arr, iterator, callback){
var completed = 0;
var iterate = function(){
iterator(arr[completed], function(err){
if(err){
callback(err);
callback = function(){};
}
else {
completed++;
if(completed == arr.length) callback();
else iterate();
}
});
};
iterate();
};

exports.map = function(arr, iterator, callback){
var results = [];
exports.forEach(arr, function(x, callback){
iterator(x, function(err, v){
results.push(v);
callback(err);
});
}, function(err){
callback(err, results);
});
};

exports.mapSeries = function(arr, iterator, callback){
var results = [];
exports.forEachSeries(arr, function(x, callback){
iterator(x, function(err, v){
results.push(v);
callback(err);
});
}, function(err){
callback(err, results);
});
};

exports.reduce = function(arr, memo, iterator, callback){
exports.forEach(arr, function(x, callback){
iterator(memo, x, function(err, v){
memo = v;
callback(err);
});
}, function(err){
callback(err, memo);
});
};

exports.reduceSeries = function(arr, memo, iterator, callback){
exports.forEachSeries(arr, function(x, callback){
iterator(memo, x, function(err, v){
memo = v;
callback(err);
});
}, function(err){
callback(err, memo);
});
};

exports.filter = function(arr, iterator, callback){
var results = [];
exports.forEach(arr, function(x, callback){
iterator(x, function(v){
if(v) results.push(x);
callback();
});
}, function(err){
callback(results);
});
};

exports.filterSeries = function(arr, iterator, callback){
var results = [];
exports.forEachSeries(arr, function(x, callback){
iterator(x, function(v){
if(v) results.push(x);
callback();
});
}, function(err){
callback(results);
});
};

exports.some = function(arr, iterator, main_callback){
exports.forEach(arr, function(x, callback){
iterator(x, function(v){
if(v){
main_callback(true);
main_callback = function(){};
}
callback();
});
}, function(err){
main_callback(false);
});
};

exports.every = function(arr, iterator, main_callback){
exports.forEach(arr, function(x, callback){
iterator(x, function(v){
if(!v){
main_callback(false);
main_callback = function(){};
}
callback();
});
}, function(err){
main_callback(true);
});
};
219 changes: 219 additions & 0 deletions test/test-async.js
Expand Up @@ -261,3 +261,222 @@ exports.testIteratorNext = function(test){
test.equals(iterator2.next(), undefined);
test.done();
};

exports.testForEach = function(test){
var args = [];
async.forEach([1,3,2], function(x, callback){
setTimeout(function(){
args.push(x);
callback();
}, x*50);
}, function(err){
test.same(args, [1,2,3]);
test.done();
});
};

exports.testForEachError = function(test){
test.expect(1);
async.forEach([1,2,3], function(x, callback){
callback('error');
}, function(err){
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testForEachSeries = function(test){
var args = [];
async.forEachSeries([1,3,2], function(x, callback){
setTimeout(function(){
args.push(x);
callback();
}, x*50);
}, function(err){
test.same(args, [1,3,2]);
test.done();
});
};

exports.testForEachSeriesError = function(test){
test.expect(2);
var call_order = [];
async.forEachSeries([1,2,3], function(x, callback){
call_order.push(x);
callback('error');
}, function(err){
test.same(call_order, [1]);
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testMap = function(test){
async.map([1,3,2], function(x, callback){
setTimeout(function(){
callback(null, x*2);
}, x*50);
}, function(err, results){
test.same(results, [2,4,6]);
test.done();
});
};

exports.testMapError = function(test){
test.expect(1);
async.map([1,2,3], function(x, callback){
callback('error');
}, function(err, results){
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testMapSeries = function(test){
async.mapSeries([1,3,2], function(x, callback){
setTimeout(function(){
callback(null, x*2);
}, x*50);
}, function(err, results){
test.same(results, [2,6,4]);
test.done();
});
};

exports.testMapSeriesError = function(test){
test.expect(1);
async.mapSeries([1,2,3], function(x, callback){
callback('error');
}, function(err, results){
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testReduce = function(test){
async.reduce([1,3,2], 0, function(a, x, callback){
callback(null, a + x);
}, function(err, result){
test.equals(result, 6);
test.done();
});
};

exports.testReduceError = function(test){
test.expect(1);
async.reduce([1,2,3], 0, function(a, x, callback){
callback('error');
}, function(err, result){
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testReduceSeries = function(test){
async.reduceSeries([1,3,2], [], function(a, x, callback){
callback(null, a.concat(x));
}, function(err, result){
test.same(result, [1,3,2]);
test.done();
});
};

exports.testReduceSeriesError = function(test){
test.expect(1);
async.reduceSeries([1,2,3], 0, function(a, x, callback){
callback('error');
}, function(err, result){
test.equals(err, 'error');
});
setTimeout(test.done, 100);
};

exports.testFilter = function(test){
async.filter([3,1,2], function(x, callback){
setTimeout(function(){callback(x % 2);}, x*50);
}, function(results){
test.same(results, [1,3]);
test.done();
});
};

exports.testFilterSeries = function(test){
async.filterSeries([3,1,2], function(x, callback){
setTimeout(function(){callback(x % 2);}, x*50);
}, function(results){
test.same(results, [3,1]);
test.done();
});
};

exports.testSomeTrue = function(test){
async.some([3,1,2], function(x, callback){
process.nextTick(function(){
callback(x === 1);
});
}, function(result){
test.equals(result, true);
test.done();
});
};

exports.testSomeFalse = function(test){
async.some([3,1,2], function(x, callback){
process.nextTick(function(){
callback(x === 10);
});
}, function(result){
test.equals(result, false);
test.done();
});
};

exports.testSomeEarlyReturn = function(test){
var call_order = [];
async.some([1,2,3], function(x, callback){
setTimeout(function(){
call_order.push(x);
callback(x === 1);
}, x*50);
}, function(result){
call_order.push('callback');
});
setTimeout(function(){
test.same(call_order, [1,'callback',2,3]);
test.done();
}, 200);
};

exports.testEveryTrue = function(test){
async.every([1,2,3], function(x, callback){
process.nextTick(function(){callback(true);});
}, function(result){
test.equals(result, true);
test.done();
});
};

exports.testEveryFalse = function(test){
async.every([1,2,3], function(x, callback){
process.nextTick(function(){callback(x % 2);});
}, function(result){
test.equals(result, false);
test.done();
});
};

exports.testEveryEarlyReturn = function(test){
var call_order = [];
async.every([1,2,3], function(x, callback){
setTimeout(function(){
call_order.push(x);
callback(x === 1);
}, x*50);
}, function(result){
call_order.push('callback');
});
setTimeout(function(){
test.same(call_order, [1,2,'callback',3]);
test.done();
}, 200);
};

0 comments on commit 950183f

Please sign in to comment.