diff options
-rw-r--r-- | lib/async.js | 22 | ||||
-rwxr-xr-x | perf/benchmark.js | 6 | ||||
-rw-r--r-- | perf/suites.js | 24 | ||||
-rwxr-xr-x | test/test-async.js | 60 |
4 files changed, 107 insertions, 5 deletions
diff --git a/lib/async.js b/lib/async.js index 4257f0d..86c810a 100644 --- a/lib/async.js +++ b/lib/async.js @@ -1282,4 +1282,26 @@ root.async = async; } + function ensureAsync(fn) { + return function (/*...args, callback*/) { + var args = _baseSlice(arguments); + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }; + } + + async.ensureAsync = ensureAsync; + }()); diff --git a/perf/benchmark.js b/perf/benchmark.js index da59216..9e57fd9 100755 --- a/perf/benchmark.js +++ b/perf/benchmark.js @@ -129,7 +129,10 @@ function createSuite(suiteConfig) { }); }, _.extend({ versionName: versionName, - setup: _.partial.apply(null, [suiteConfig.setup].concat(args)) + setup: _.partial.apply(null, [suiteConfig.setup].concat(args)), + onError: function (err) { + console.log(err.stack); + } }, benchOptions)); } @@ -143,6 +146,7 @@ function createSuite(suiteConfig) { var version = event.target.options.versionName; totalTime[version] += mean; }) + .on('error', function (err) { console.error(err); }) .on('complete', function() { var fastest = this.filter('fastest'); if (fastest.length === 2) { diff --git a/perf/suites.js b/perf/suites.js index 9a36db5..28b5a32 100644 --- a/perf/suites.js +++ b/perf/suites.js @@ -204,6 +204,30 @@ module.exports = [ fn: function (async, done) { setTimeout(done, 0); } + }, + { + name: "ensureAsync sync", + fn: function (async, done) { + async.ensureAsync(function (cb) { + cb(); + })(done); + } + }, + { + name: "ensureAsync async", + fn: function (async, done) { + async.ensureAsync(function (cb) { + setImmediate(cb); + })(done); + } + }, + { + name: "ensureAsync async noWrap", + fn: function (async, done) { + (function (cb) { + setImmediate(cb); + }(done)); + } } ]; diff --git a/test/test-async.js b/test/test-async.js index 81c1787..6797afe 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -1030,12 +1030,12 @@ exports['parallel does not continue replenishing after error'] = function (test) } setTimeout(function(){ callback(); - }, delay); + }, delay); } async.parallelLimit(arr, limit, function(x, callback) { - }, function(err){}); + }, function(err){}); setTimeout(function(){ test.equal(started, 3); @@ -1438,7 +1438,7 @@ exports['eachLimit does not continue replenishing after error'] = function (test setTimeout(function(){ callback(); }, delay); - }, function(err){}); + }, function(err){}); setTimeout(function(){ test.equal(started, 3); @@ -1743,7 +1743,7 @@ exports['mapLimit does not continue replenishing after error'] = function (test) setTimeout(function(){ callback(); }, delay); - }, function(err){}); + }, function(err){}); setTimeout(function(){ test.equal(started, 3); @@ -3561,3 +3561,55 @@ exports['queue started'] = function(test) { }; +exports['ensureAsync'] = { + 'defer sync functions': function (test) { + var sync = true; + async.ensureAsync(function (arg1, arg2, cb) { + test.equal(arg1, 1); + test.equal(arg2, 2); + cb(null, 4, 5); + })(1, 2, function (err, arg4, arg5) { + test.equal(err, null); + test.equal(arg4, 4); + test.equal(arg5, 5); + test.ok(!sync, 'callback called on same tick'); + test.done(); + }); + sync = false; + }, + + 'do not defer async functions': function (test) { + var sync = false; + async.ensureAsync(function (arg1, arg2, cb) { + test.equal(arg1, 1); + test.equal(arg2, 2); + async.setImmediate(function () { + sync = true; + cb(null, 4, 5); + sync = false; + }); + })(1, 2, function (err, arg4, arg5) { + test.equal(err, null); + test.equal(arg4, 4); + test.equal(arg5, 5); + test.ok(sync, 'callback called on next tick'); + test.done(); + }); + }, + + 'double wrapping': function (test) { + var sync = true; + async.ensureAsync(async.ensureAsync(function (arg1, arg2, cb) { + test.equal(arg1, 1); + test.equal(arg2, 2); + cb(null, 4, 5); + }))(1, 2, function (err, arg4, arg5) { + test.equal(err, null); + test.equal(arg4, 4); + test.equal(arg5, 5); + test.ok(!sync, 'callback called on same tick'); + test.done(); + }); + sync = false; + } +}; |