summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Early <alexander.early@gmail.com>2017-03-25 15:26:14 -0700
committerAlexander Early <alexander.early@gmail.com>2017-03-25 15:26:14 -0700
commitdb9face308f5d00ca98c8d3c2080949b1db50ab7 (patch)
treefa70cc16dc33fbb4921dcde8deae8b3578b5640a
parentffd66850df894a5a961c8f2d21d75d0796448ce9 (diff)
downloadasync-db9face308f5d00ca98c8d3c2080949b1db50ab7.tar.gz
handle async funcs in control flow methods
-rw-r--r--lib/auto.js3
-rw-r--r--lib/autoInject.js15
-rw-r--r--lib/doDuring.js7
-rw-r--r--lib/doWhilst.js8
-rw-r--r--lib/during.js9
-rw-r--r--lib/forever.js3
-rw-r--r--lib/internal/applyEach.js4
-rw-r--r--lib/internal/parallel.js3
-rw-r--r--lib/internal/queue.js23
-rw-r--r--lib/internal/wrapAsync.js7
-rw-r--r--lib/queue.js4
-rw-r--r--lib/race.js3
-rw-r--r--lib/retry.js5
-rw-r--r--lib/retryable.js4
-rw-r--r--lib/seq.js5
-rw-r--r--lib/timesLimit.js4
-rw-r--r--lib/waterfall.js3
-rw-r--r--lib/whilst.js6
-rw-r--r--mocha_test/es2017/asyncFunctions.js342
19 files changed, 418 insertions, 40 deletions
diff --git a/lib/auto.js b/lib/auto.js
index fe98e06..4d7bf32 100644
--- a/lib/auto.js
+++ b/lib/auto.js
@@ -8,6 +8,7 @@ import rest from './internal/rest';
import once from './internal/once';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* Determines the best order for running the functions in `tasks`, based on
@@ -213,7 +214,7 @@ export default function (tasks, concurrency, callback) {
}));
runningTasks++;
- var taskFn = task[task.length - 1];
+ var taskFn = wrapAsync(task[task.length - 1]);
if (task.length > 1) {
taskFn(results, taskCallback);
} else {
diff --git a/lib/autoInject.js b/lib/autoInject.js
index b0f5735..9efd295 100644
--- a/lib/autoInject.js
+++ b/lib/autoInject.js
@@ -3,8 +3,10 @@ import forOwn from 'lodash/_baseForOwn';
import arrayMap from 'lodash/_arrayMap';
import isArray from 'lodash/isArray';
import trim from 'lodash/trim';
+import wrapAsync from './internal/wrapAsync';
+import { isAsync } from './internal/wrapAsync';
-var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
+var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /(=.+)?(\s*)$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
@@ -106,22 +108,25 @@ export default function autoInject(tasks, callback) {
forOwn(tasks, function (taskFn, key) {
var params;
+ var fnIsAsync = isAsync(taskFn);
if (isArray(taskFn)) {
params = taskFn.slice(0, -1);
taskFn = taskFn[taskFn.length - 1];
newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
- } else if (taskFn.length === 1) {
+ } else if ((!fnIsAsync && taskFn.length === 1) ||
+ (fnIsAsync && taskFn.length === 0)) {
// no dependencies, use the function as-is
newTasks[key] = taskFn;
} else {
params = parseParams(taskFn);
- if (taskFn.length === 0 && params.length === 0) {
+ if (taskFn.length === 0 && !fnIsAsync && params.length === 0) {
throw new Error("autoInject task functions require explicit parameters.");
}
- params.pop();
+ // remove callback param
+ if (!fnIsAsync) params.pop();
newTasks[key] = params.concat(newTask);
}
@@ -131,7 +136,7 @@ export default function autoInject(tasks, callback) {
return results[name];
});
newArgs.push(taskCb);
- taskFn.apply(null, newArgs);
+ wrapAsync(taskFn).apply(null, newArgs);
}
});
diff --git a/lib/doDuring.js b/lib/doDuring.js
index b198d17..e79574b 100644
--- a/lib/doDuring.js
+++ b/lib/doDuring.js
@@ -1,6 +1,7 @@
import noop from 'lodash/noop';
import rest from './internal/rest';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in
@@ -25,17 +26,19 @@ import onlyOnce from './internal/onlyOnce';
*/
export default function doDuring(fn, test, callback) {
callback = onlyOnce(callback || noop);
+ var _fn = wrapAsync(fn);
+ var _test = wrapAsync(test);
var next = rest(function(err, args) {
if (err) return callback(err);
args.push(check);
- test.apply(this, args);
+ _test.apply(this, args);
});
function check(err, truth) {
if (err) return callback(err);
if (!truth) return callback(null);
- fn(next);
+ _fn(next);
}
check(null, true);
diff --git a/lib/doWhilst.js b/lib/doWhilst.js
index d9222aa..39f4600 100644
--- a/lib/doWhilst.js
+++ b/lib/doWhilst.js
@@ -2,6 +2,7 @@ import noop from 'lodash/noop';
import rest from './internal/rest';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
@@ -19,7 +20,7 @@ import onlyOnce from './internal/onlyOnce';
* passes. The function is passed a `callback(err)`, which must be called once
* it has completed with an optional `err` argument. Invoked with (callback).
* @param {Function} test - synchronous truth test to perform after each
- * execution of `iteratee`. Invoked with the non-error callback results of
+ * execution of `iteratee`. Invoked with the non-error callback results of
* `iteratee`.
* @param {Function} [callback] - A callback which is called after the test
* function has failed and repeated execution of `iteratee` has stopped.
@@ -28,10 +29,11 @@ import onlyOnce from './internal/onlyOnce';
*/
export default function doWhilst(iteratee, test, callback) {
callback = onlyOnce(callback || noop);
+ var _iteratee = wrapAsync(iteratee);
var next = rest(function(err, args) {
if (err) return callback(err);
- if (test.apply(this, args)) return iteratee(next);
+ if (test.apply(this, args)) return _iteratee(next);
callback.apply(null, [null].concat(args));
});
- iteratee(next);
+ _iteratee(next);
}
diff --git a/lib/during.js b/lib/during.js
index 549ad44..dd9ba99 100644
--- a/lib/during.js
+++ b/lib/during.js
@@ -1,5 +1,6 @@
import noop from 'lodash/noop';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that
@@ -40,17 +41,19 @@ import onlyOnce from './internal/onlyOnce';
*/
export default function during(test, fn, callback) {
callback = onlyOnce(callback || noop);
+ var _fn = wrapAsync(fn);
+ var _test = wrapAsync(test);
function next(err) {
if (err) return callback(err);
- test(check);
+ _test(check);
}
function check(err, truth) {
if (err) return callback(err);
if (!truth) return callback(null);
- fn(next);
+ _fn(next);
}
- test(check);
+ _test(check);
}
diff --git a/lib/forever.js b/lib/forever.js
index 0147395..d1f3256 100644
--- a/lib/forever.js
+++ b/lib/forever.js
@@ -2,6 +2,7 @@ import noop from 'lodash/noop';
import onlyOnce from './internal/onlyOnce';
import ensureAsync from './ensureAsync';
+import wrapAsync from './internal/wrapAsync';
/**
* Calls the asynchronous function `fn` with a callback parameter that allows it
@@ -34,7 +35,7 @@ import ensureAsync from './ensureAsync';
*/
export default function forever(fn, errback) {
var done = onlyOnce(errback || noop);
- var task = ensureAsync(fn);
+ var task = ensureAsync(wrapAsync(fn));
function next(err) {
if (err) return done(err);
diff --git a/lib/internal/applyEach.js b/lib/internal/applyEach.js
index aca2b7d..f611def 100644
--- a/lib/internal/applyEach.js
+++ b/lib/internal/applyEach.js
@@ -1,11 +1,13 @@
+import arrayMap from 'lodash/_arrayMap'
import rest from './rest';
import initialParams from './initialParams';
+import wrapAsync from './wrapAsync';
export default function applyEach(eachfn) {
return rest(function(fns, args) {
var go = initialParams(function(args, callback) {
var that = this;
- return eachfn(fns, function (fn, cb) {
+ return eachfn(arrayMap(fns, wrapAsync), function (fn, cb) {
fn.apply(that, args.concat(cb));
}, callback);
});
diff --git a/lib/internal/parallel.js b/lib/internal/parallel.js
index d7c5cd9..70993d3 100644
--- a/lib/internal/parallel.js
+++ b/lib/internal/parallel.js
@@ -1,13 +1,14 @@
import noop from 'lodash/noop';
import isArrayLike from 'lodash/isArrayLike';
import rest from './rest';
+import wrapAsync from './wrapAsync';
export default function _parallel(eachfn, tasks, callback) {
callback = callback || noop;
var results = isArrayLike(tasks) ? [] : {};
eachfn(tasks, function (task, key, callback) {
- task(rest(function (err, args) {
+ wrapAsync(task)(rest(function (err, args) {
if (args.length <= 1) {
args = args[0];
}
diff --git a/lib/internal/queue.js b/lib/internal/queue.js
index 7a438da..c825e62 100644
--- a/lib/internal/queue.js
+++ b/lib/internal/queue.js
@@ -6,6 +6,7 @@ import rest from './rest';
import onlyOnce from './onlyOnce';
import setImmediate from './setImmediate';
import DLL from './DoublyLinkedList';
+import wrapAsync from './wrapAsync';
export default function queue(worker, concurrency, payload) {
if (concurrency == null) {
@@ -15,6 +16,10 @@ export default function queue(worker, concurrency, payload) {
throw new Error('Concurrency must not be zero');
}
+ var _worker = wrapAsync(worker);
+ var numRunning = 0;
+ var workersList = [];
+
function _insert(data, insertAtFront, callback) {
if (callback != null && typeof callback !== 'function') {
throw new Error('task callback must be a function');
@@ -47,7 +52,7 @@ export default function queue(worker, concurrency, payload) {
function _next(tasks) {
return rest(function(args){
- workers -= 1;
+ numRunning -= 1;
for (var i = 0, l = tasks.length; i < l; i++) {
var task = tasks[i];
@@ -63,7 +68,7 @@ export default function queue(worker, concurrency, payload) {
}
}
- if (workers <= (q.concurrency - q.buffer) ) {
+ if (numRunning <= (q.concurrency - q.buffer) ) {
q.unsaturated();
}
@@ -74,8 +79,6 @@ export default function queue(worker, concurrency, payload) {
});
}
- var workers = 0;
- var workersList = [];
var isProcessing = false;
var q = {
_tasks: new DLL(),
@@ -106,7 +109,7 @@ export default function queue(worker, concurrency, payload) {
return;
}
isProcessing = true;
- while(!q.paused && workers < q.concurrency && q._tasks.length){
+ while(!q.paused && numRunning < q.concurrency && q._tasks.length){
var tasks = [], data = [];
var l = q._tasks.length;
if (q.payload) l = Math.min(l, q.payload);
@@ -119,15 +122,15 @@ export default function queue(worker, concurrency, payload) {
if (q._tasks.length === 0) {
q.empty();
}
- workers += 1;
+ numRunning += 1;
workersList.push(tasks[0]);
- if (workers === q.concurrency) {
+ if (numRunning === q.concurrency) {
q.saturated();
}
var cb = onlyOnce(_next(tasks));
- worker(data, cb);
+ _worker(data, cb);
}
isProcessing = false;
},
@@ -135,13 +138,13 @@ export default function queue(worker, concurrency, payload) {
return q._tasks.length;
},
running: function () {
- return workers;
+ return numRunning;
},
workersList: function () {
return workersList;
},
idle: function() {
- return q._tasks.length + workers === 0;
+ return q._tasks.length + numRunning === 0;
},
pause: function () {
q.paused = true;
diff --git a/lib/internal/wrapAsync.js b/lib/internal/wrapAsync.js
index 2cfafd4..aee0275 100644
--- a/lib/internal/wrapAsync.js
+++ b/lib/internal/wrapAsync.js
@@ -7,8 +7,7 @@ function supportsAsync() {
var supported;
try {
/* eslint no-eval: 0 */
- supported = supportsSymbol &&
- isAsync(eval('(async function () {})'));
+ supported = isAsync(eval('(async function () {})'));
} catch (e) {
supported = false;
}
@@ -16,7 +15,7 @@ function supportsAsync() {
}
function isAsync(fn) {
- return fn[Symbol.toStringTag] === 'AsyncFunction';
+ return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction';
}
function wrapAsync(asyncFn) {
@@ -25,4 +24,4 @@ function wrapAsync(asyncFn) {
export default supportsAsync() ? wrapAsync : identity;
-export { supportsAsync };
+export { supportsAsync, isAsync };
diff --git a/lib/queue.js b/lib/queue.js
index 5666843..0f17cd9 100644
--- a/lib/queue.js
+++ b/lib/queue.js
@@ -1,4 +1,5 @@
import queue from './internal/queue';
+import wrapAsync from './internal/wrapAsync';
/**
* A queue of tasks for the worker function to complete.
@@ -101,7 +102,8 @@ import queue from './internal/queue';
* });
*/
export default function (worker, concurrency) {
+ var _worker = wrapAsync(worker);
return queue(function (items, cb) {
- worker(items[0], cb);
+ _worker(items[0], cb);
}, concurrency, 1);
}
diff --git a/lib/race.js b/lib/race.js
index 5547c86..ee81b37 100644
--- a/lib/race.js
+++ b/lib/race.js
@@ -1,6 +1,7 @@
import isArray from 'lodash/isArray';
import noop from 'lodash/noop';
import once from './internal/once';
+import wrapAsync from './internal/wrapAsync';
/**
* Runs the `tasks` array of functions in parallel, without waiting until the
@@ -44,6 +45,6 @@ export default function race(tasks, callback) {
if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
if (!tasks.length) return callback();
for (var i = 0, l = tasks.length; i < l; i++) {
- tasks[i](callback);
+ wrapAsync(tasks[i])(callback);
}
}
diff --git a/lib/retry.js b/lib/retry.js
index a5ad866..e279016 100644
--- a/lib/retry.js
+++ b/lib/retry.js
@@ -1,5 +1,6 @@
import noop from 'lodash/noop';
import constant from 'lodash/constant';
+import wrapAsync from './internal/wrapAsync';
/**
* Attempts to get a successful response from `task` no more than `times` times
@@ -124,9 +125,11 @@ export default function retry(opts, task, callback) {
throw new Error("Invalid arguments for async.retry");
}
+ var _task = wrapAsync(task);
+
var attempt = 1;
function retryAttempt() {
- task(function(err) {
+ _task(function(err) {
if (err && attempt++ < options.times &&
(typeof options.errorFilter != 'function' ||
options.errorFilter(err))) {
diff --git a/lib/retryable.js b/lib/retryable.js
index a541977..6fba8e2 100644
--- a/lib/retryable.js
+++ b/lib/retryable.js
@@ -1,5 +1,6 @@
import retry from './retry';
import initialParams from './internal/initialParams';
+import wrapAsync from './internal/wrapAsync';
/**
* A close relative of [`retry`]{@link module:ControlFlow.retry}. This method wraps a task and makes it
@@ -30,9 +31,10 @@ export default function (opts, task) {
task = opts;
opts = null;
}
+ var _task = wrapAsync(task);
return initialParams(function (args, callback) {
function taskFn(cb) {
- task.apply(null, args.concat(cb));
+ _task.apply(null, args.concat(cb));
}
if (opts) retry(opts, taskFn, callback);
diff --git a/lib/seq.js b/lib/seq.js
index 8bd1121..9a35847 100644
--- a/lib/seq.js
+++ b/lib/seq.js
@@ -1,6 +1,8 @@
import noop from 'lodash/noop';
import rest from './internal/rest';
import reduce from './reduce';
+import wrapAsync from './internal/wrapAsync';
+import arrayMap from 'lodash/_arrayMap';
/**
* Version of the compose function that is more natural to read. Each function
@@ -41,6 +43,7 @@ import reduce from './reduce';
* });
*/
export default rest(function seq(functions) {
+ var _functions = arrayMap(functions, wrapAsync);
return rest(function(args) {
var that = this;
@@ -51,7 +54,7 @@ export default rest(function seq(functions) {
cb = noop;
}
- reduce(functions, args, function(newargs, fn, cb) {
+ reduce(_functions, args, function(newargs, fn, cb) {
fn.apply(that, newargs.concat(rest(function(err, nextargs) {
cb(err, nextargs);
})));
diff --git a/lib/timesLimit.js b/lib/timesLimit.js
index 68d5ede..7ba91d6 100644
--- a/lib/timesLimit.js
+++ b/lib/timesLimit.js
@@ -1,5 +1,6 @@
import mapLimit from './mapLimit';
import range from 'lodash/_baseRange';
+import wrapAsync from './internal/wrapAsync';
/**
* The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
@@ -18,5 +19,6 @@ import range from 'lodash/_baseRange';
* @param {Function} callback - see [async.map]{@link module:Collections.map}.
*/
export default function timeLimit(count, limit, iteratee, callback) {
- mapLimit(range(0, count, 1), limit, iteratee, callback);
+ var _iteratee = wrapAsync(iteratee);
+ mapLimit(range(0, count, 1), limit, _iteratee, callback);
}
diff --git a/lib/waterfall.js b/lib/waterfall.js
index 7bc60da..cb2c1fd 100644
--- a/lib/waterfall.js
+++ b/lib/waterfall.js
@@ -4,6 +4,7 @@ import once from './internal/once';
import rest from './internal/rest';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* Runs the `tasks` array of functions in series, each passing their results to
@@ -82,7 +83,7 @@ export default function(tasks, callback) {
args.push(taskCallback);
- var task = tasks[taskIndex++];
+ var task = wrapAsync(tasks[taskIndex++]);
task.apply(null, args);
}
diff --git a/lib/whilst.js b/lib/whilst.js
index ac2a79c..8135af7 100644
--- a/lib/whilst.js
+++ b/lib/whilst.js
@@ -2,6 +2,7 @@ import noop from 'lodash/noop';
import rest from './internal/rest';
import onlyOnce from './internal/onlyOnce';
+import wrapAsync from './internal/wrapAsync';
/**
* Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
@@ -40,11 +41,12 @@ import onlyOnce from './internal/onlyOnce';
*/
export default function whilst(test, iteratee, callback) {
callback = onlyOnce(callback || noop);
+ var _iteratee = wrapAsync(iteratee);
if (!test()) return callback(null);
var next = rest(function(err, args) {
if (err) return callback(err);
- if (test()) return iteratee(next);
+ if (test()) return _iteratee(next);
callback.apply(null, [null].concat(args));
});
- iteratee(next);
+ _iteratee(next);
}
diff --git a/mocha_test/es2017/asyncFunctions.js b/mocha_test/es2017/asyncFunctions.js
index 68accd8..dc22f62 100644
--- a/mocha_test/es2017/asyncFunctions.js
+++ b/mocha_test/es2017/asyncFunctions.js
@@ -28,6 +28,10 @@ module.exports = function () {
})
});
+ /*
+ * Collections
+ */
+
it('should handle async functions in each', (done) => {
async.each(input, asyncIdentity, done);
});
@@ -252,4 +256,342 @@ module.exports = function () {
done(err);
});
});
+
+ /*
+ * Control Flow
+ */
+
+ it('should handle async functions in applyEach', (done) => {
+ async.applyEach([asyncIdentity, asyncIdentity])(input, (err, result) => {
+ expect(result).to.eql([input, input]);
+ done(err);
+ });
+ });
+
+ it('should handle async functions in applyEachSeries', (done) => {
+ async.applyEachSeries([asyncIdentity, asyncIdentity])(input, (err, result) => {
+ expect(result).to.eql([input, input]);
+ done(err);
+ });
+ });
+
+ it('should handle async functions in auto', (done) => {
+ async.auto({
+ a: async function () {
+ return await Promise.resolve(1);
+ },
+ b: async function () {
+ return await Promise.resolve(2);
+ },
+ c: ['a', 'b', async function (results) {
+ return await Promise.resolve(results.a + results.b);
+ }]
+ }, (err, result) => {
+ expect(result).to.eql({a: 1, b: 2, c: 3});
+ done(err);
+ });
+ });
+
+ it('should handle async functions in autoInject', (done) => {
+ async.autoInject({
+ a: async function () {
+ return await Promise.resolve(1);
+ },
+ b: async function (a) {
+ return await Promise.resolve(a + 1);
+ },
+ c: async (a, b) => {
+ return await Promise.resolve(a + b);
+ },
+ d: async (c) => {
+ return await Promise.resolve(c + 1);
+ }
+ }, (err, result) => {
+ expect(result).to.eql({a: 1, b: 2, c: 3, d: 4});
+ done(err);
+ });
+ });
+
+ it('should handle async functions in cargo', (done) => {
+ var result = [];
+ var q = async.cargo(async function(val) {
+ result.push(await Promise.resolve(val));
+ }, 2)
+
+ q.drain = () => {
+ expect(result).to.eql([[1, 2], [3]]);
+ done();
+ };
+
+ q.push(1);
+ q.push(2);
+ q.push(3);
+ });
+
+ it('should handle async functions in queue', (done) => {
+ var result = [];
+ var q = async.queue(async function(val) {
+ result.push(await Promise.resolve(val));
+ }, 2)
+
+ q.drain = () => {
+ expect(result).to.eql([1, 2, 3]);
+ done();
+ };
+
+ q.push(1);
+ q.push(2);
+ q.push(3);
+ });
+
+ it('should handle async functions in priorityQueue', (done) => {
+ var result = [];
+ var q = async.priorityQueue(async function(val) {
+ result.push(await Promise.resolve(val));
+ }, 2)
+
+ q.drain = () => {
+ expect(result).to.eql([1, 2, 3]);
+ done();
+ };
+
+ q.push(1);
+ q.push(2);
+ q.push(3);
+ });
+
+ it('should handle async functions in compose', (done) => {
+ async.compose(
+ async (a) => a + 1,
+ async (a) => a + 1,
+ async (a) => a + 1
+ )(0, (err, result) => {
+ expect(result).to.equal(3);
+ done(err);
+ });
+ });
+
+ it('should handle async functions in seq', (done) => {
+ async.seq(
+ async (a) => a + 1,
+ async (a) => a + 1,
+ async (a) => a + 1
+ )(0, (err, result) => {
+ expect(result).to.equal(3);
+ done(err);
+ });
+ });
+
+ it('should handle async functions in during', (done) => {
+ var val = 0;
+ async.during(async () => {
+ return val < 3;
+ },
+ async () => {
+ val += 1;
+ return val;
+ }, done);
+ });
+
+ it('should handle async functions in doDuring', (done) => {
+ var val = 0;
+ async.doDuring(async () => {
+ val += 1;
+ return val;
+ },
+ async (res) => {
+ return res < 3;
+ }, done);
+ });
+
+ it('should handle async functions in whilst', (done) => {
+ var val = 0;
+ async.whilst(() => val < 3,
+ async () => {
+ val += 1;
+ return val;
+ }, done);
+ });
+
+ it('should handle async functions in doWhilst', (done) => {
+ var val = 0;
+ async.doWhilst(async () => {
+ val += 1;
+ return val;
+ }, (res) => res < 3, done);
+ });
+
+ it('should handle async functions in until', (done) => {
+ var val = 0;
+ async.until(() => val > 3,
+ async () => {
+ val += 1;
+ return val;
+ }, done);
+ });
+
+ it('should handle async functions in doUntil', (done) => {
+ var val = 0;
+ async.doUntil(async () => {
+ val += 1;
+ return val;
+ }, (res) => res > 3, done);
+ });
+
+ it('should handle async functions in forever', (done) => {
+ var counter = 0;
+ async.forever(async () => {
+ counter += 1;
+ if (counter > 10) throw new Error('too big');
+ },(err) => {
+ expect(err.message).to.equal('too big');
+ done();
+ })
+ });
+
+ it('should handle async functions in parallel', (done) => {
+ async.parallel([
+ async () => 1,
+ async () => 2,
+ async () => 3
+ ], (err, result) => {
+ expect(result).to.eql([1, 2, 3]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in parallel (object)', (done) => {
+ async.parallel({
+ a: async () => 1,
+ b: async () => 2,
+ c: async () => 3
+ }, (err, result) => {
+ expect(result).to.eql({a: 1, b: 2, c: 3});
+ done(err);
+ })
+ });
+
+ it('should handle async functions in parallelLimit', (done) => {
+ async.parallelLimit([
+ async () => 1,
+ async () => 2,
+ async () => 3
+ ], 2, (err, result) => {
+ expect(result).to.eql([1, 2, 3]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in parallelLimit (object)', (done) => {
+ async.parallelLimit({
+ a: async () => 1,
+ b: async () => 2,
+ c: async () => 3
+ }, 2, (err, result) => {
+ expect(result).to.eql({a: 1, b: 2, c: 3});
+ done(err);
+ })
+ });
+
+ it('should handle async functions in series', (done) => {
+ async.series([
+ async () => 1,
+ async () => 2,
+ async () => 3
+ ], (err, result) => {
+ expect(result).to.eql([1, 2, 3]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in series (object)', (done) => {
+ async.series({
+ a: async () => 1,
+ b: async () => 2,
+ c: async () => 3
+ }, (err, result) => {
+ expect(result).to.eql({a: 1, b: 2, c: 3});
+ done(err);
+ })
+ });
+
+ it('should handle async functions in race', (done) => {
+ async.race([
+ async () => 1,
+ async () => 2,
+ async () => 3
+ ], (err, result) => {
+ expect(result).to.eql(1);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in retry', (done) => {
+ var count = 0;
+ async.retry(4, async () => {
+ count += 1;
+ if (count < 3) throw new Error('fail');
+ return count;
+ }, (err, result) => {
+ expect(result).to.eql(3);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in retryable', (done) => {
+ var count = 0;
+ async.retryable(4, async () => {
+ count += 1;
+ if (count < 3) throw new Error('fail');
+ return count;
+ })((err, result) => {
+ expect(result).to.eql(3);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in times', (done) => {
+ var count = 0;
+ async.times(4, async () => {
+ count += 1;
+ return count;
+ }, (err, result) => {
+ expect(result).to.eql([1, 2, 3, 4]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in timesLimit', (done) => {
+ var count = 0;
+ async.timesLimit(4, 2, async () => {
+ count += 1;
+ return count;
+ }, (err, result) => {
+ expect(result).to.eql([1, 2, 3, 4]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in timesSeries', (done) => {
+ var count = 0;
+ async.timesSeries(4, async () => {
+ count += 1;
+ return count;
+ }, (err, result) => {
+ expect(result).to.eql([1, 2, 3, 4]);
+ done(err);
+ })
+ });
+
+ it('should handle async functions in waterfall', (done) => {
+ async.waterfall([
+ async () => 1,
+ async (a) => a + 1,
+ async (a) => [a, a + 1],
+ async ([a, b]) => a + b,
+ ], (err, result) => {
+ expect(result).to.eql(5);
+ done(err);
+ })
+ });
}