eachOf.js

  1. import isArrayLike from 'lodash/isArrayLike';
  2. import breakLoop from './internal/breakLoop';
  3. import eachOfLimit from './eachOfLimit';
  4. import doLimit from './internal/doLimit';
  5. import noop from 'lodash/noop';
  6. import once from './internal/once';
  7. import onlyOnce from './internal/onlyOnce';
  8. import wrapAsync from './internal/wrapAsync';
  9. // eachOf implementation optimized for array-likes
  10. function eachOfArrayLike(coll, iteratee, callback) {
  11. callback = once(callback || noop);
  12. var index = 0,
  13. completed = 0,
  14. length = coll.length;
  15. if (length === 0) {
  16. callback(null);
  17. }
  18. function iteratorCallback(err, value) {
  19. if (err) {
  20. callback(err);
  21. } else if ((++completed === length) || value === breakLoop) {
  22. callback(null);
  23. }
  24. }
  25. for (; index < length; index++) {
  26. iteratee(coll[index], index, onlyOnce(iteratorCallback));
  27. }
  28. }
  29. // a generic version of eachOf which can handle array, object, and iterator cases.
  30. var eachOfGeneric = doLimit(eachOfLimit, Infinity);
  31. /**
  32. * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
  33. * to the iteratee.
  34. *
  35. * @name eachOf
  36. * @static
  37. * @memberOf module:Collections
  38. * @method
  39. * @alias forEachOf
  40. * @category Collection
  41. * @see [async.each]{@link module:Collections.each}
  42. * @param {Array|Iterable|Object} coll - A collection to iterate over.
  43. * @param {AsyncFunction} iteratee - A function to apply to each
  44. * item in `coll`.
  45. * The `key` is the item's key, or index in the case of an array.
  46. * Invoked with (item, key, callback).
  47. * @param {Function} [callback] - A callback which is called when all
  48. * `iteratee` functions have finished, or an error occurs. Invoked with (err).
  49. * @example
  50. *
  51. * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
  52. * var configs = {};
  53. *
  54. * async.forEachOf(obj, function (value, key, callback) {
  55. * fs.readFile(__dirname + value, "utf8", function (err, data) {
  56. * if (err) return callback(err);
  57. * try {
  58. * configs[key] = JSON.parse(data);
  59. * } catch (e) {
  60. * return callback(e);
  61. * }
  62. * callback();
  63. * });
  64. * }, function (err) {
  65. * if (err) console.error(err.message);
  66. * // configs is now a map of JSON data
  67. * doSomethingWith(configs);
  68. * });
  69. */
  70. export default function(coll, iteratee, callback) {
  71. var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
  72. eachOfImplementation(coll, wrapAsync(iteratee), callback);
  73. }