diff options
author | Alexander Early <alexander.early@gmail.com> | 2018-09-02 19:46:23 -0700 |
---|---|---|
committer | Alexander Early <alexander.early@gmail.com> | 2018-09-02 19:46:23 -0700 |
commit | 4a33ff9790d57c2f669dfcbeede39857f6157281 (patch) | |
tree | e3fd527a7eab95a0514066fba62245635e2be023 | |
parent | 4c5358987647bc25792b6b89a0dfd03dcf6bed59 (diff) | |
download | async-4a33ff9790d57c2f669dfcbeede39857f6157281.tar.gz |
awaitable auto
-rw-r--r-- | lib/auto.js | 13 | ||||
-rw-r--r-- | lib/autoInject.js | 3 | ||||
-rw-r--r-- | lib/internal/once.js | 6 | ||||
-rw-r--r-- | test/es2017/awaitableFunctions.js | 41 |
4 files changed, 54 insertions, 9 deletions
diff --git a/lib/auto.js b/lib/auto.js index b06e3c5..ad92d74 100644 --- a/lib/auto.js +++ b/lib/auto.js @@ -1,8 +1,7 @@ -import noop from './internal/noop'; - import once from './internal/once'; import onlyOnce from './internal/onlyOnce'; import wrapAsync from './internal/wrapAsync'; +import { promiseCallback, PROMISE_SYMBOL } from './internal/promiseCallback' /** * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on @@ -42,7 +41,7 @@ import wrapAsync from './internal/wrapAsync'; * pass an error to their callback. Results are always returned; however, if an * error occurs, no further `tasks` will be performed, and the results object * will only contain partial results. Invoked with (err, results). - * @returns undefined + * @returns {Promise} a promise, if a callback is not passed * @example * * async.auto({ @@ -83,13 +82,13 @@ import wrapAsync from './internal/wrapAsync'; * console.log('results = ', results); * }); */ -export default function (tasks, concurrency, callback) { - if (typeof concurrency === 'function') { +export default function auto(tasks, concurrency, callback) { + if (typeof concurrency !== 'number') { // concurrency is optional, shift the args. callback = concurrency; concurrency = null; } - callback = once(callback || noop); + callback = once(callback || promiseCallback()); var numTasks = Object.keys(tasks).length; if (!numTasks) { return callback(null); @@ -251,4 +250,6 @@ export default function (tasks, concurrency, callback) { }); return result; } + + return callback[PROMISE_SYMBOL] } diff --git a/lib/autoInject.js b/lib/autoInject.js index 004cfda..996fceb 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -54,6 +54,7 @@ function parseParams(func) { * the tasks have been completed. It receives the `err` argument if any `tasks` * pass an error to their callback, and a `results` object with any completed * task results, similar to `auto`. + * @returns {Promise} a promise, if no callback is passed * @example * * // The example from `auto` can be rewritten as follows: @@ -142,5 +143,5 @@ export default function autoInject(tasks, callback) { } }); - auto(newTasks, callback); + return auto(newTasks, callback); } diff --git a/lib/internal/once.js b/lib/internal/once.js index 1293d5e..10ab26b 100644 --- a/lib/internal/once.js +++ b/lib/internal/once.js @@ -1,8 +1,10 @@ export default function once(fn) { - return function (...args) { + function wrapper (...args) { if (fn === null) return; var callFn = fn; fn = null; callFn.apply(this, args); - }; + } + Object.assign(wrapper, fn) + return wrapper } diff --git a/test/es2017/awaitableFunctions.js b/test/es2017/awaitableFunctions.js index 7967d90..92fcd3b 100644 --- a/test/es2017/awaitableFunctions.js +++ b/test/es2017/awaitableFunctions.js @@ -311,4 +311,45 @@ module.exports = function () { await async.transform(inputObj, async (...args) => calls.push(args)); expect(calls).to.eql([[{}, 1, 'a'], [{}, 2, 'b'], [{}, 3, 'c']]) }); + + /* + * Control flow + */ + + // TODO: figure out to do with applyEach + + it('should return a Promise: auto', async () => { + expect (async.auto.name).to.contain('auto') + const calls = [] + await async.auto({ + async a () { + calls.push('a') + return Promise.resolve('a') + }, + b: ['a', 'c', async () => calls.push('b')], + async c () { + await Promise.resolve() + calls.push('c') + return Promise.resolve('c') + } + }); + expect(calls).to.eql(['a', 'c', 'b']) + }); + it('should return a Promise: autoInject', async () => { + expect (async.autoInject.name).to.contain('autoInject') + const calls = [] + await async.autoInject({ + async a () { + calls.push('a') + return 'a' + }, + async b(a, c) { calls.push('b'); calls.push(a, c) }, + async c () { + calls.push('c') + return 'c' + } + }, 1); + expect(calls).to.eql(['a', 'c', 'b', 'a', 'c']) + }); + }; |