diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/index.js | 9 | ||||
-rw-r--r-- | lib/internal/map.js | 9 | ||||
-rw-r--r-- | lib/internal/setImmediate.js | 33 | ||||
-rw-r--r-- | lib/map.js | 6 | ||||
-rw-r--r-- | lib/mapValues.js | 46 | ||||
-rw-r--r-- | lib/mapValuesLimit.js | 33 | ||||
-rw-r--r-- | lib/mapValuesSeries.js | 21 | ||||
-rw-r--r-- | lib/nextTick.js | 16 |
8 files changed, 154 insertions, 19 deletions
diff --git a/lib/index.js b/lib/index.js index 1180dcf..091f657 100644 --- a/lib/index.js +++ b/lib/index.js @@ -43,6 +43,9 @@ import log from './log'; import map from './map'; import mapLimit from './mapLimit'; import mapSeries from './mapSeries'; +import mapValues from './mapValues'; +import mapValuesLimit from './mapValuesLimit'; +import mapValuesSeries from './mapValuesSeries'; import memoize from './memoize'; import nextTick from './nextTick'; import parallel from './parallel'; @@ -115,6 +118,9 @@ export default { map: map, mapLimit: mapLimit, mapSeries: mapSeries, + mapValues: mapValues, + mapValuesLimit: mapValuesLimit, + mapValuesSeries: mapValuesSeries, memoize: memoize, nextTick: nextTick, parallel: parallel, @@ -205,6 +211,9 @@ export { map as map, mapLimit as mapLimit, mapSeries as mapSeries, + mapValues as mapValues, + mapValuesLimit as mapValuesLimit, + mapValuesSeries as mapValuesSeries, memoize as memoize, nextTick as nextTick, parallel as parallel, diff --git a/lib/internal/map.js b/lib/internal/map.js index 45c3eae..2c2a750 100644 --- a/lib/internal/map.js +++ b/lib/internal/map.js @@ -1,13 +1,14 @@ -import isArrayLike from 'lodash/isArrayLike'; -import getIterator from './getIterator'; import noop from 'lodash/noop'; import once from './once'; export default function _asyncMap(eachfn, arr, iteratee, callback) { callback = once(callback || noop); arr = arr || []; - var results = isArrayLike(arr) || getIterator(arr) ? [] : {}; - eachfn(arr, function (value, index, callback) { + var results = []; + var counter = 0; + + eachfn(arr, function (value, _, callback) { + var index = counter++; iteratee(value, function (err, v) { results[index] = v; callback(err); diff --git a/lib/internal/setImmediate.js b/lib/internal/setImmediate.js index 7d15249..eb4ea63 100644 --- a/lib/internal/setImmediate.js +++ b/lib/internal/setImmediate.js @@ -1,21 +1,30 @@ 'use strict'; + import rest from 'lodash/rest'; -var _setImmediate = typeof setImmediate === 'function' && setImmediate; +export var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; +export var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; + +export function fallback(fn) { + setTimeout(fn, 0); +} + +export function wrap(defer) { + return rest(function (fn, args) { + defer(function () { + fn.apply(null, args); + }); + }); +} var _defer; -if (_setImmediate) { - _defer = _setImmediate; -} else if (typeof process === 'object' && typeof process.nextTick === 'function') { + +if (hasSetImmediate) { + _defer = setImmediate; +} else if (hasNextTick) { _defer = process.nextTick; } else { - _defer = function(fn) { - setTimeout(fn, 0); - }; + _defer = fallback; } -export default rest(function (fn, args) { - _defer(function () { - fn.apply(null, args); - }); -}); +export default wrap(_defer); @@ -14,6 +14,10 @@ import doLimit from './internal/doLimit'; * in order. However, the results array will be in the same order as the * original `coll`. * + * If `map` is passed an Object, the results will be an Array. The results + * will roughly be in the order of the original Objects' keys (but this can + * vary across JavaScript engines) + * * @name map * @static * @memberOf async @@ -24,7 +28,7 @@ import doLimit from './internal/doLimit'; * once it has completed with an error (which can be `null`) and a * transformed item. Invoked with (item, callback). * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Results is an array of the + * functions have finished, or an error occurs. Results is an Array of the * transformed items from the `coll`. Invoked with (err, results). * @example * diff --git a/lib/mapValues.js b/lib/mapValues.js new file mode 100644 index 0000000..83ffc43 --- /dev/null +++ b/lib/mapValues.js @@ -0,0 +1,46 @@ +import mapValuesLimit from './mapValuesLimit'; +import doLimit from './internal/doLimit'; + + +/** + * A relative of `map`, designed for use with objects. + * + * Produces a new Object by mapping each value of `obj` through the `iteratee` + * function. The `iteratee` is called each `value` and `key` from `obj` and a + * callback for when it has finished processing. Each of these callbacks takes + * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` + * passes an error to its callback, the main `callback` (for the `mapValues` + * function) is immediately called with the error. + * + * Note, the order of the keys in the result is not guaranteed. The keys will + * be roughly in the order they complete, (but this is very engine-specific) + * + * @name mapValues + * @static + * @memberOf async + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {Function} iteratee - A function to apply to each value and key in + * `coll`. The iteratee is passed a `callback(err, transformed)` which must be + * called once it has completed with an error (which can be `null`) and a + * transformed value. Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `obj`. Invoked with (err, result). + * @example + * + * async.mapValues({ + * f1: 'file1', + * f2: 'file2', + * f3: 'file3' + * }, fs.stat, function(err, result) { + * // results is now a map of stats for each file, e.g. + * // { + * // f1: [stats for file1], + * // f2: [stats for file2], + * // f3: [stats for file3] + * // } + * }); + */ + +export default doLimit(mapValuesLimit, Infinity); diff --git a/lib/mapValuesLimit.js b/lib/mapValuesLimit.js new file mode 100644 index 0000000..762b871 --- /dev/null +++ b/lib/mapValuesLimit.js @@ -0,0 +1,33 @@ +import eachOfLimit from './eachOfLimit'; + +/** + * The same as `mapValues` but runs a maximum of `limit` async operations at a + * time. + * + * @name mapValuesLimit + * @static + * @memberOf async + * @see async.mapValues + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A function to apply to each value in `obj`. + * The iteratee is passed a `callback(err, transformed)` which must be called + * once it has completed with an error (which can be `null`) and a + * transformed value. Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an object of the + * transformed values from the `obj`. Invoked with (err, result). + */ +export default function mapValuesLimit(obj, limit, iteratee, callback) { + var newObj = {}; + eachOfLimit(obj, limit, function(val, key, next) { + iteratee(val, key, function (err, result) { + if (err) return next(err); + newObj[key] = result; + next(); + }); + }, function (err) { + callback(err, newObj); + }); +} diff --git a/lib/mapValuesSeries.js b/lib/mapValuesSeries.js new file mode 100644 index 0000000..163d474 --- /dev/null +++ b/lib/mapValuesSeries.js @@ -0,0 +1,21 @@ +import mapValuesLimit from './mapValuesLimit'; +import doLimit from './internal/doLimit'; + +/** + * The same as `mapValues` but runs only a single async operation at a time. + * + * @name mapValuesSeries + * @static + * @memberOf async + * @see async.mapValues + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {Function} iteratee - A function to apply to each value in `obj`. + * The iteratee is passed a `callback(err, transformed)` which must be called + * once it has completed with an error (which can be `null`) and a + * transformed value. Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an object of the + * transformed values from the `obj`. Invoked with (err, result). + */ +export default doLimit(mapValuesLimit, 1); diff --git a/lib/nextTick.js b/lib/nextTick.js index 66a4c1f..a69b87e 100644 --- a/lib/nextTick.js +++ b/lib/nextTick.js @@ -1,4 +1,6 @@ -import setImmediate from './internal/setImmediate'; +'use strict'; + +import { hasNexTick, hasSetImmediate, fallback, wrap } from './internal/setImmediate'; /** * Calls `callback` on a later loop around the event loop. In Node.js this just @@ -30,4 +32,14 @@ import setImmediate from './internal/setImmediate'; * // a, b, and c equal 1, 2, and 3 * }, 1, 2, 3); */ -export default setImmediate; +var _defer; + +if (hasNexTick) { + _defer = process.nextTick; +} else if (hasSetImmediate) { + _defer = setImmediate; +} else { + _defer = fallback; +} + +export default wrap(_defer); |