[Pkg-javascript-commits] [node-async] 279/480: added async.compose

Jonas Smedegaard js at moszumanska.debian.org
Fri May 2 08:58:34 UTC 2014


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository node-async.

commit 53e004ee782f2af588191eed45482d5f76a0349d
Author: Caolan McMahon <caolan at caolanmcmahon.com>
Date:   Thu Feb 7 17:25:34 2013 +0000

    added async.compose
---
 README.md          | 39 ++++++++++++++++++++++++
 lib/async.js       | 18 +++++++++++
 test/test-async.js | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)

diff --git a/README.md b/README.md
index 5f343ef..d7ab284 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,7 @@ So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:
 * [until](#until)
 * [doUntil](#doUntil)
 * [waterfall](#waterfall)
+* [compose](#compose)
 * [queue](#queue)
 * [cargo](#cargo)
 * [auto](#auto)
@@ -787,6 +788,44 @@ async.waterfall([
 ```
 
 ---------------------------------------
+<a name="compose" />
+### compose(fn1, fn2...)
+
+Creates a function which is a composition of the passed asynchronous
+functions. Each function consumes the return value of the function that
+follows. Composing functions f(), g() and h() would produce the result of
+f(g(h())), only this version uses callbacks to obtain the return values.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+function add1(n, callback) {
+    setTimeout(function () [
+        callback(null, n + 1);
+    }, 10);
+}
+
+function mul3(n, callback) {
+    setTimeout(function () [
+        callback(null, n * 3);
+    }, 10);
+}
+
+var add1mul3 = async.compose(mul3, add1);
+
+add1mul3(4, function (err, result) {
+   // result now equals 15
+});
+```
+
+---------------------------------------
 
 <a name="queue" />
 ### queue(worker, concurrency)
diff --git a/lib/async.js b/lib/async.js
index 5f2fb18..7305d9a 100755
--- a/lib/async.js
+++ b/lib/async.js
@@ -915,6 +915,24 @@
         return async.mapSeries(counter, iterator, callback);
     };
 
+    async.compose = function (/* functions... */) {
+        var fns = Array.prototype.reverse.call(arguments);
+        return function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            async.reduce(fns, args, function (newargs, fn, cb) {
+                fn.apply(that, newargs.concat([function () {
+                    var err = arguments[0];
+                    var nextargs = Array.prototype.slice.call(arguments, 1);
+                    cb(err, nextargs);
+                }]))
+            },
+            function (err, results) {
+                callback.apply(that, [err].concat(results));
+            });
+        };
+    };
 
     // AMD / RequireJS
     if (typeof define !== 'undefined' && define.amd) {
diff --git a/test/test-async.js b/test/test-async.js
index 323527a..8414c22 100755
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -66,6 +66,93 @@ function getFunctionsObject(call_order) {
     };
 }
 
+exports['compose'] = function (test) {
+    test.expect(4);
+    var add2 = function (n, cb) {
+        test.equal(n, 3);
+        setTimeout(function () {
+            cb(null, n + 2);
+        }, 50);
+    };
+    var mul3 = function (n, cb) {
+        test.equal(n, 5);
+        setTimeout(function () {
+            cb(null, n * 3);
+        }, 15);
+    };
+    var add1 = function (n, cb) {
+        test.equal(n, 15);
+        setTimeout(function () {
+            cb(null, n + 1);
+        }, 100);
+    };
+    var add2mul3add1 = async.compose(add1, mul3, add2);
+    add2mul3add1(3, function (err, result) {
+        if (err) {
+            return test.done(err);
+        }
+        test.equal(result, 16);
+        test.done();
+    });
+};
+
+exports['compose error'] = function (test) {
+    test.expect(3);
+    var testerr = new Error('test');
+
+    var add2 = function (n, cb) {
+        test.equal(n, 3);
+        setTimeout(function () {
+            cb(null, n + 2);
+        }, 50);
+    };
+    var mul3 = function (n, cb) {
+        test.equal(n, 5);
+        setTimeout(function () {
+            cb(testerr);
+        }, 15);
+    };
+    var add1 = function (n, cb) {
+        test.ok(false, 'add1 should not get called');
+        setTimeout(function () {
+            cb(null, n + 1);
+        }, 100);
+    };
+    var add2mul3add1 = async.compose(add1, mul3, add2);
+    add2mul3add1(3, function (err, result) {
+        test.equal(err, testerr);
+        test.done();
+    });
+};
+
+exports['compose binding'] = function (test) {
+    test.expect(4);
+    var testerr = new Error('test');
+    var testcontext = {name: 'foo'};
+
+    var add2 = function (n, cb) {
+        test.equal(this, testcontext);
+        setTimeout(function () {
+            cb(null, n + 2);
+        }, 50);
+    };
+    var mul3 = function (n, cb) {
+        test.equal(this, testcontext);
+        setTimeout(function () {
+            cb(null, n * 3);
+        }, 15);
+    };
+    var add2mul3 = async.compose(mul3, add2);
+    add2mul3.call(testcontext, 3, function (err, result) {
+        if (err) {
+            return test.done(err);
+        }
+        test.equal(this, testcontext);
+        test.equal(result, 15);
+        test.done();
+    });
+};
+
 exports['auto'] = function(test){
     var callOrder = [];
     var testdata = [{test: 'test'}];

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-async.git



More information about the Pkg-javascript-commits mailing list