summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsharp.maestro <sharp.maestro@gmail.com>2013-11-07 18:59:21 +0400
committersharp.maestro <sharp.maestro@gmail.com>2013-11-07 18:59:21 +0400
commit8439c17dbe8308fc7563d34c99787ba1cf73d876 (patch)
treee0e8b38224ca9c00f2be682e75035063e564a281
parente345e1e29d41483d6064a8edb7645824bf5d47e2 (diff)
downloadasync-8439c17dbe8308fc7563d34c99787ba1cf73d876.tar.gz
added seq function: natural to read version of compose
-rw-r--r--README.md46
-rwxr-xr-xlib/async.js8
-rwxr-xr-xtest/test-async.js87
3 files changed, 139 insertions, 2 deletions
diff --git a/README.md b/README.md
index aff0040..8e2a78e 100644
--- a/README.md
+++ b/README.md
@@ -125,6 +125,7 @@ So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:
* [forever](#forever)
* [waterfall](#waterfall)
* [compose](#compose)
+* [seq](#seq)
* [applyEach](#applyEach)
* [queue](#queue)
* [cargo](#cargo)
@@ -874,6 +875,51 @@ add1mul3(4, function (err, result) {
```
---------------------------------------
+<a name="seq" />
+### seq(fn1, fn2...)
+
+Version of the compose function that is more natural to read.
+Each following function consumes the return value of the latter function.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+// Requires lodash (or underscore), express3 and dresende's orm2
+// Part of an app, that fetches cats of the logged user.
+app.get('/cats', function(request, response) {
+ function handleError(err, data, callback) {
+ if (err) {
+ console.error(err);
+ response.json({ status: 'error', message: err.message });
+ }
+ else {
+ callback(data);
+ }
+ }
+ var User = request.models.User;
+ asyc.seq(
+ _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data))
+ handleError,
+ function(user, fn) {
+ user.getCats(fn); // 'getCats' has signature (callback(err, data))
+ },
+ handleError,
+ function(cats) {
+ response.json({ status: 'ok', message: 'Cats found', data: cats });
+ }
+ )(req.session.user_id);
+ }
+});
+```
+
+---------------------------------------
<a name="applyEach" />
### applyEach(fns, args..., callback)
diff --git a/lib/async.js b/lib/async.js
index cb6320d..63aa9c0 100755
--- a/lib/async.js
+++ b/lib/async.js
@@ -884,8 +884,8 @@
return async.mapSeries(counter, iterator, callback);
};
- async.compose = function (/* functions... */) {
- var fns = Array.prototype.reverse.call(arguments);
+ async.seq = function (/* functions... */) {
+ var fns = arguments;
return function () {
var that = this;
var args = Array.prototype.slice.call(arguments);
@@ -903,6 +903,10 @@
};
};
+ async.compose = function (/* functions... */) {
+ return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+ };
+
var _applyEach = function (eachfn, fns /*args...*/) {
var go = function () {
var that = this;
diff --git a/test/test-async.js b/test/test-async.js
index ff401e7..1b6be04 100755
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -261,6 +261,93 @@ exports['compose binding'] = function (test) {
});
};
+exports['seq'] = 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.seq(add2, mul3, add1);
+ add2mul3add1(3, function (err, result) {
+ if (err) {
+ return test.done(err);
+ }
+ test.equal(result, 16);
+ test.done();
+ });
+};
+
+exports['seq 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.seq(add2, mul3, add1);
+ add2mul3add1(3, function (err, result) {
+ test.equal(err, testerr);
+ test.done();
+ });
+};
+
+exports['seq 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.seq(add2, mul3);
+ 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'}];