From f4dbaf601b1fc6f9436d200ef716dc5a47870423 Mon Sep 17 00:00:00 2001 From: Caolan McMahon Date: Sun, 3 Mar 2013 11:25:18 +0000 Subject: add applyEach function --- README.md | 31 ++++++++++++++++++++++++++++ lib/async.js | 19 +++++++++++++++++ test/test-async.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/README.md b/README.md index 2535cf8..9927c98 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: * [doUntil](#doUntil) * [waterfall](#waterfall) * [compose](#compose) +* [applyEach](#applyEach) * [queue](#queue) * [cargo](#cargo) * [auto](#auto) @@ -832,6 +833,36 @@ add1mul3(4, function (err, result) { }); ``` +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling the +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. + +__Arguments__ + +* fns - the asynchronous functions to all call with the same arguments +* args... - any number of separate arguments to pass to the function +* callback - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + --------------------------------------- diff --git a/lib/async.js b/lib/async.js index a805447..ad3982a 100755 --- a/lib/async.js +++ b/lib/async.js @@ -945,6 +945,25 @@ }; }; + async.applyEach = function (fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return async.each(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 1) { + var args = Array.prototype.slice.call(arguments, 1); + return go.apply(this, args); + } + else { + return go; + } + }; + // AMD / RequireJS if (typeof define !== 'undefined' && define.amd) { define([], function () { diff --git a/test/test-async.js b/test/test-async.js index 1caf1bc..5bd72bf 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -66,6 +66,66 @@ function getFunctionsObject(call_order) { }; } +exports['applyEach'] = function (test) { + test.expect(4); + var call_order = []; + var one = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('one'); + cb(null, 1); + }, 100); + }; + var two = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('two'); + cb(null, 2); + }, 50); + }; + var three = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('three'); + cb(null, 3); + }, 150); + }; + async.applyEach([one, two, three], 5, function (err) { + test.same(call_order, ['two', 'one', 'three']); + test.done(); + }); +}; + +exports['applyEach partial application'] = function (test) { + test.expect(4); + var call_order = []; + var one = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('one'); + cb(null, 1); + }, 100); + }; + var two = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('two'); + cb(null, 2); + }, 50); + }; + var three = function (val, cb) { + test.equal(val, 5); + setTimeout(function () { + call_order.push('three'); + cb(null, 3); + }, 150); + }; + async.applyEach([one, two, three])(5, function (err) { + test.same(call_order, ['two', 'one', 'three']); + test.done(); + }); +}; + exports['compose'] = function (test) { test.expect(4); var add2 = function (n, cb) { -- cgit v1.2.1