reduce.js

  1. import eachOfSeries from './eachOfSeries';
  2. import noop from 'lodash/noop';
  3. import once from './internal/once';
  4. import wrapAsync from './internal/wrapAsync';
  5. /**
  6. * Reduces `coll` into a single value using an async `iteratee` to return each
  7. * successive step. `memo` is the initial state of the reduction. This function
  8. * only operates in series.
  9. *
  10. * For performance reasons, it may make sense to split a call to this function
  11. * into a parallel map, and then use the normal `Array.prototype.reduce` on the
  12. * results. This function is for situations where each step in the reduction
  13. * needs to be async; if you can get the data before reducing it, then it's
  14. * probably a good idea to do so.
  15. *
  16. * @name reduce
  17. * @static
  18. * @memberOf module:Collections
  19. * @method
  20. * @alias inject
  21. * @alias foldl
  22. * @category Collection
  23. * @param {Array|Iterable|Object} coll - A collection to iterate over.
  24. * @param {*} memo - The initial state of the reduction.
  25. * @param {AsyncFunction} iteratee - A function applied to each item in the
  26. * array to produce the next step in the reduction.
  27. * The `iteratee` should complete with the next state of the reduction.
  28. * If the iteratee complete with an error, the reduction is stopped and the
  29. * main `callback` is immediately called with the error.
  30. * Invoked with (memo, item, callback).
  31. * @param {Function} [callback] - A callback which is called after all the
  32. * `iteratee` functions have finished. Result is the reduced value. Invoked with
  33. * (err, result).
  34. * @example
  35. *
  36. * async.reduce([1,2,3], 0, function(memo, item, callback) {
  37. * // pointless async:
  38. * process.nextTick(function() {
  39. * callback(null, memo + item)
  40. * });
  41. * }, function(err, result) {
  42. * // result is now equal to the last value of memo, which is 6
  43. * });
  44. */
  45. export default function reduce(coll, memo, iteratee, callback) {
  46. callback = once(callback || noop);
  47. var _iteratee = wrapAsync(iteratee);
  48. eachOfSeries(coll, function(x, i, callback) {
  49. _iteratee(memo, x, function(err, v) {
  50. memo = v;
  51. callback(err);
  52. });
  53. }, function(err) {
  54. callback(err, memo);
  55. });
  56. }