@@ -887,6 +887,105 @@ function _eachOfLimit(limit) {
887887 } ;
888888}
889889
890+ /**
891+ * Take a sync function and make it async, passing its return value to a
892+ * callback. This is useful for plugging sync functions into a waterfall,
893+ * series, or other async functions. Any arguments passed to the generated
894+ * function will be passed to the wrapped function (except for the final
895+ * callback argument). Errors thrown will be passed to the callback.
896+ *
897+ * If the function passed to `asyncify` returns a Promise, that promises's
898+ * resolved/rejected state will be used to call the callback, rather than simply
899+ * the synchronous return value.
900+ *
901+ * This also means you can asyncify ES2016 `async` functions.
902+ *
903+ * @name asyncify
904+ * @static
905+ * @memberOf module:Utils
906+ * @method
907+ * @alias wrapSync
908+ * @category Util
909+ * @param {Function } func - The synchronous function to convert to an
910+ * asynchronous function.
911+ * @returns {Function } An asynchronous wrapper of the `func`. To be invoked with
912+ * (callback).
913+ * @example
914+ *
915+ * // passing a regular synchronous function
916+ * async.waterfall([
917+ * async.apply(fs.readFile, filename, "utf8"),
918+ * async.asyncify(JSON.parse),
919+ * function (data, next) {
920+ * // data is the result of parsing the text.
921+ * // If there was a parsing error, it would have been caught.
922+ * }
923+ * ], callback);
924+ *
925+ * // passing a function returning a promise
926+ * async.waterfall([
927+ * async.apply(fs.readFile, filename, "utf8"),
928+ * async.asyncify(function (contents) {
929+ * return db.model.create(contents);
930+ * }),
931+ * function (model, next) {
932+ * // `model` is the instantiated model object.
933+ * // If there was an error, this function would be skipped.
934+ * }
935+ * ], callback);
936+ *
937+ * // es2017 example
938+ * var q = async.queue(async.asyncify(async function(file) {
939+ * var intermediateStep = await processFile(file);
940+ * return await somePromise(intermediateStep)
941+ * }));
942+ *
943+ * q.push(files);
944+ */
945+ function asyncify ( func ) {
946+ return initialParams ( function ( args , callback ) {
947+ var result ;
948+ try {
949+ result = func . apply ( this , args ) ;
950+ } catch ( e ) {
951+ return callback ( e ) ;
952+ }
953+ // if result is Promise object
954+ if ( isObject ( result ) && typeof result . then === 'function' ) {
955+ result . then ( function ( value ) {
956+ callback ( null , value ) ;
957+ } , function ( err ) {
958+ callback ( err . message ? err : new Error ( err ) ) ;
959+ } ) ;
960+ } else {
961+ callback ( null , result ) ;
962+ }
963+ } ) ;
964+ }
965+
966+ var supportsSymbol = typeof Symbol !== 'undefined' ;
967+
968+ function supportsAsync ( ) {
969+ var supported ;
970+ try {
971+ /* eslint no-eval: 0 */
972+ supported = supportsSymbol && isAsync ( eval ( '(async function () {})' ) ) ;
973+ } catch ( e ) {
974+ supported = false ;
975+ }
976+ return supported ;
977+ }
978+
979+ function isAsync ( fn ) {
980+ return fn [ Symbol . toStringTag ] === 'AsyncFunction' ;
981+ }
982+
983+ var wrapAsync$1 = supportsAsync ( ) ? function wrapAsync ( asyncFn ) {
984+ if ( ! supportsSymbol ) return asyncFn ;
985+
986+ return isAsync ( asyncFn ) ? asyncify ( asyncFn ) : asyncFn ;
987+ } : identity ;
988+
890989/**
891990 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
892991 * time.
@@ -910,7 +1009,7 @@ function _eachOfLimit(limit) {
9101009 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
9111010 */
9121011function eachOfLimit ( coll , limit , iteratee , callback ) {
913- _eachOfLimit ( limit ) ( coll , iteratee , callback ) ;
1012+ _eachOfLimit ( limit ) ( coll , wrapAsync$1 ( iteratee ) , callback ) ;
9141013}
9151014
9161015function doLimit ( fn , limit ) {
@@ -988,7 +1087,7 @@ var eachOfGeneric = doLimit(eachOfLimit, Infinity);
9881087 */
9891088var eachOf = function ( coll , iteratee , callback ) {
9901089 var eachOfImplementation = isArrayLike ( coll ) ? eachOfArrayLike : eachOfGeneric ;
991- eachOfImplementation ( coll , iteratee , callback ) ;
1090+ eachOfImplementation ( coll , wrapAsync$1 ( iteratee ) , callback ) ;
9921091} ;
9931092
9941093function doParallel ( fn ) {
@@ -1002,10 +1101,11 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
10021101 arr = arr || [ ] ;
10031102 var results = [ ] ;
10041103 var counter = 0 ;
1104+ var _iteratee = wrapAsync$1 ( iteratee ) ;
10051105
10061106 eachfn ( arr , function ( value , _ , callback ) {
10071107 var index = counter ++ ;
1008- iteratee ( value , function ( err , v ) {
1108+ _iteratee ( value , function ( err , v ) {
10091109 results [ index ] = v ;
10101110 callback ( err ) ;
10111111 } ) ;
@@ -1205,82 +1305,6 @@ var apply$2 = rest(function (fn, args) {
12051305 } ) ;
12061306} ) ;
12071307
1208- /**
1209- * Take a sync function and make it async, passing its return value to a
1210- * callback. This is useful for plugging sync functions into a waterfall,
1211- * series, or other async functions. Any arguments passed to the generated
1212- * function will be passed to the wrapped function (except for the final
1213- * callback argument). Errors thrown will be passed to the callback.
1214- *
1215- * If the function passed to `asyncify` returns a Promise, that promises's
1216- * resolved/rejected state will be used to call the callback, rather than simply
1217- * the synchronous return value.
1218- *
1219- * This also means you can asyncify ES2016 `async` functions.
1220- *
1221- * @name asyncify
1222- * @static
1223- * @memberOf module:Utils
1224- * @method
1225- * @alias wrapSync
1226- * @category Util
1227- * @param {Function } func - The synchronous function to convert to an
1228- * asynchronous function.
1229- * @returns {Function } An asynchronous wrapper of the `func`. To be invoked with
1230- * (callback).
1231- * @example
1232- *
1233- * // passing a regular synchronous function
1234- * async.waterfall([
1235- * async.apply(fs.readFile, filename, "utf8"),
1236- * async.asyncify(JSON.parse),
1237- * function (data, next) {
1238- * // data is the result of parsing the text.
1239- * // If there was a parsing error, it would have been caught.
1240- * }
1241- * ], callback);
1242- *
1243- * // passing a function returning a promise
1244- * async.waterfall([
1245- * async.apply(fs.readFile, filename, "utf8"),
1246- * async.asyncify(function (contents) {
1247- * return db.model.create(contents);
1248- * }),
1249- * function (model, next) {
1250- * // `model` is the instantiated model object.
1251- * // If there was an error, this function would be skipped.
1252- * }
1253- * ], callback);
1254- *
1255- * // es6 example
1256- * var q = async.queue(async.asyncify(async function(file) {
1257- * var intermediateStep = await processFile(file);
1258- * return await somePromise(intermediateStep)
1259- * }));
1260- *
1261- * q.push(files);
1262- */
1263- function asyncify ( func ) {
1264- return initialParams ( function ( args , callback ) {
1265- var result ;
1266- try {
1267- result = func . apply ( this , args ) ;
1268- } catch ( e ) {
1269- return callback ( e ) ;
1270- }
1271- // if result is Promise object
1272- if ( isObject ( result ) && typeof result . then === 'function' ) {
1273- result . then ( function ( value ) {
1274- callback ( null , value ) ;
1275- } , function ( err ) {
1276- callback ( err . message ? err : new Error ( err ) ) ;
1277- } ) ;
1278- } else {
1279- callback ( null , result ) ;
1280- }
1281- } ) ;
1282- }
1283-
12841308/**
12851309 * A specialized version of `_.forEach` for arrays without support for
12861310 * iteratee shorthands.
@@ -3083,7 +3107,7 @@ function _withoutIndex(iteratee) {
30833107 * });
30843108 */
30853109function eachLimit ( coll , iteratee , callback ) {
3086- eachOf ( coll , _withoutIndex ( iteratee ) , callback ) ;
3110+ eachOf ( coll , _withoutIndex ( wrapAsync$1 ( iteratee ) ) , callback ) ;
30873111}
30883112
30893113/**
@@ -3108,7 +3132,7 @@ function eachLimit(coll, iteratee, callback) {
31083132 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
31093133 */
31103134function eachLimit$1 ( coll , limit , iteratee , callback ) {
3111- _eachOfLimit ( limit ) ( coll , _withoutIndex ( iteratee ) , callback ) ;
3135+ _eachOfLimit ( limit ) ( coll , _withoutIndex ( wrapAsync$1 ( iteratee ) ) , callback ) ;
31123136}
31133137
31143138/**
@@ -3318,7 +3342,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
33183342
33193343function _filter ( eachfn , coll , iteratee , callback ) {
33203344 var filter = isArrayLike ( coll ) ? filterArray : filterGeneric ;
3321- filter ( eachfn , coll , iteratee , callback || noop ) ;
3345+ filter ( eachfn , coll , wrapAsync$1 ( iteratee ) , callback || noop ) ;
33223346}
33233347
33243348/**
0 commit comments