summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/each.js3
-rw-r--r--lib/eachOf.js8
-rw-r--r--lib/eachOfLimit.js3
-rw-r--r--lib/internal/eachOfLimit.js5
-rw-r--r--lib/internal/map.js7
-rw-r--r--lib/internal/once.js4
-rw-r--r--lib/internal/promiseCallback.js24
-rw-r--r--mocha_test/es2017/asyncFunctions.js21
8 files changed, 58 insertions, 17 deletions
diff --git a/lib/each.js b/lib/each.js
index 29f2baf..28c9cb4 100644
--- a/lib/each.js
+++ b/lib/each.js
@@ -25,6 +25,7 @@ import wrapAsync from './internal/wrapAsync'
* If you need the index, use `eachOf`.
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if the callback is omitted
* @example
*
* // assuming openFiles is an array of file names and saveFile is a function
@@ -60,5 +61,5 @@ import wrapAsync from './internal/wrapAsync'
* });
*/
export default function eachLimit(coll, iteratee, callback) {
- eachOf(coll, withoutIndex(wrapAsync(iteratee)), callback);
+ return eachOf(coll, withoutIndex(wrapAsync(iteratee)), callback);
}
diff --git a/lib/eachOf.js b/lib/eachOf.js
index 9ab3eb6..c27738e 100644
--- a/lib/eachOf.js
+++ b/lib/eachOf.js
@@ -3,14 +3,14 @@ import isArrayLike from 'lodash/isArrayLike';
import breakLoop from './internal/breakLoop';
import eachOfLimit from './eachOfLimit';
import doLimit from './internal/doLimit';
-import noop from 'lodash/noop';
import once from './internal/once';
import onlyOnce from './internal/onlyOnce';
import wrapAsync from './internal/wrapAsync';
+import promiseCallback from './internal/promiseCallback';
// eachOf implementation optimized for array-likes
function eachOfArrayLike(coll, iteratee, callback) {
- callback = once(callback || noop);
+ callback = once(callback || promiseCallback());
var index = 0,
completed = 0,
length = coll.length;
@@ -29,6 +29,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
for (; index < length; index++) {
iteratee(coll[index], index, onlyOnce(iteratorCallback));
}
+ return callback.promise;
}
// a generic version of eachOf which can handle array, object, and iterator cases.
@@ -52,6 +53,7 @@ var eachOfGeneric = doLimit(eachOfLimit, Infinity);
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if the callback is omitted
* @example
*
* var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
@@ -75,5 +77,5 @@ var eachOfGeneric = doLimit(eachOfLimit, Infinity);
*/
export default function(coll, iteratee, callback) {
var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
- eachOfImplementation(coll, wrapAsync(iteratee), callback);
+ return eachOfImplementation(coll, wrapAsync(iteratee), callback);
}
diff --git a/lib/eachOfLimit.js b/lib/eachOfLimit.js
index 1de28ef..f5371e7 100644
--- a/lib/eachOfLimit.js
+++ b/lib/eachOfLimit.js
@@ -20,7 +20,8 @@ import wrapAsync from './internal/wrapAsync';
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
+ * @returns {Promise} a promise, if the callback is omitted
*/
export default function eachOfLimit(coll, limit, iteratee, callback) {
- _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
+ return _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
}
diff --git a/lib/internal/eachOfLimit.js b/lib/internal/eachOfLimit.js
index 0a1f5bc..7abad94 100644
--- a/lib/internal/eachOfLimit.js
+++ b/lib/internal/eachOfLimit.js
@@ -1,14 +1,14 @@
-import noop from 'lodash/noop';
import once from './once';
import iterator from './iterator';
import onlyOnce from './onlyOnce';
import breakLoop from './breakLoop';
+import promiseCallback from './promiseCallback';
export default function _eachOfLimit(limit) {
return function (obj, iteratee, callback) {
- callback = once(callback || noop);
+ callback = once(callback || promiseCallback());
if (limit <= 0 || !obj) {
return callback(null);
}
@@ -50,5 +50,6 @@ export default function _eachOfLimit(limit) {
}
replenish();
+ return callback.promise;
};
}
diff --git a/lib/internal/map.js b/lib/internal/map.js
index 9cd927e..d00c3a2 100644
--- a/lib/internal/map.js
+++ b/lib/internal/map.js
@@ -1,8 +1,9 @@
-import noop from 'lodash/noop';
+import once from './once';
import wrapAsync from './wrapAsync';
+import promiseCallback from './promiseCallback';
export default function _asyncMap(eachfn, arr, iteratee, callback) {
- callback = callback || noop;
+ callback = once(callback || promiseCallback());
arr = arr || [];
var results = [];
var counter = 0;
@@ -17,4 +18,6 @@ export default function _asyncMap(eachfn, arr, iteratee, callback) {
}, function (err) {
callback(err, results);
});
+
+ return callback.promise;
}
diff --git a/lib/internal/once.js b/lib/internal/once.js
index f601185..1094ad3 100644
--- a/lib/internal/once.js
+++ b/lib/internal/once.js
@@ -1,8 +1,10 @@
export default function once(fn) {
- return function () {
+ function wrapped () {
if (fn === null) return;
var callFn = fn;
fn = null;
callFn.apply(this, arguments);
};
+ wrapped.promise = fn.promise;
+ return wrapped;
}
diff --git a/lib/internal/promiseCallback.js b/lib/internal/promiseCallback.js
new file mode 100644
index 0000000..cbbd3ad
--- /dev/null
+++ b/lib/internal/promiseCallback.js
@@ -0,0 +1,24 @@
+import noop from 'lodash/noop';
+
+var supportsPromise = typeof Promise === 'function';
+
+export default supportsPromise ? promiseCallback : noopCallback;
+
+function noopCallback() {
+ return noop;
+}
+
+function promiseCallback() {
+ var resolve, reject;
+ function callback(err, value) {
+ if (err) return reject(err);
+ resolve(value);
+ }
+
+ callback.promise = new Promise(function (res, rej) {
+ resolve = res;
+ reject = rej;
+ })
+
+ return callback;
+}
diff --git a/mocha_test/es2017/asyncFunctions.js b/mocha_test/es2017/asyncFunctions.js
index 1a93f4f..5616307 100644
--- a/mocha_test/es2017/asyncFunctions.js
+++ b/mocha_test/es2017/asyncFunctions.js
@@ -2,6 +2,7 @@ var async = require('../../lib');
const expect = require('chai').expect;
const assert = require('assert');
+const promiseProto = Object.getPrototypeOf(new Promise(()=>{}));
module.exports = function () {
async function asyncIdentity(val) {
@@ -32,8 +33,16 @@ module.exports = function () {
* Collections
*/
- it('should handle async functions in each', (done) => {
- async.each(input, asyncIdentity, done);
+ it('should handle async functions in each', async () => {
+ var promise = async.each(input, asyncIdentity);
+ assert(typeof promise.then === 'function');
+ assert(Object.getPrototypeOf(promise) === promiseProto);
+ await promise;
+ });
+
+ it('should handle async functions in each (empty array)', async () => {
+ var promise = async.each([], asyncIdentity);
+ await promise;
});
it('should handle async functions in eachLimit', (done) => {
@@ -56,11 +65,9 @@ module.exports = function () {
async.eachOfSeries(input, asyncIdentity, done);
});
- it('should handle async functions in map', (done) => {
- async.map(input, asyncIdentity, (err, result) => {
- expect(result).to.eql(input);
- done(err);
- });
+ it('should handle async functions in map', async () => {
+ var result = await async.map(input, asyncIdentity);
+ expect(result).to.eql(input);
});
it('should handle async functions in mapLimit', (done) => {