You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.8 KiB

  1. var async = require('./async.js')
  2. , abort = require('./abort.js')
  3. ;
  4. // API
  5. module.exports = iterate;
  6. /**
  7. * Iterates over each job object
  8. *
  9. * @param {array|object} list - array or object (named list) to iterate over
  10. * @param {function} iterator - iterator to run
  11. * @param {object} state - current job status
  12. * @param {function} callback - invoked when all elements processed
  13. */
  14. function iterate(list, iterator, state, callback)
  15. {
  16. // store current index
  17. var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;
  18. state.jobs[key] = runJob(iterator, key, list[key], function(error, output)
  19. {
  20. // don't repeat yourself
  21. // skip secondary callbacks
  22. if (!(key in state.jobs))
  23. {
  24. return;
  25. }
  26. // clean up jobs
  27. delete state.jobs[key];
  28. if (error)
  29. {
  30. // don't process rest of the results
  31. // stop still active jobs
  32. // and reset the list
  33. abort(state);
  34. }
  35. else
  36. {
  37. state.results[key] = output;
  38. }
  39. // return salvaged results
  40. callback(error, state.results);
  41. });
  42. }
  43. /**
  44. * Runs iterator over provided job element
  45. *
  46. * @param {function} iterator - iterator to invoke
  47. * @param {string|number} key - key/index of the element in the list of jobs
  48. * @param {mixed} item - job description
  49. * @param {function} callback - invoked after iterator is done with the job
  50. * @returns {function|mixed} - job abort function or something else
  51. */
  52. function runJob(iterator, key, item, callback)
  53. {
  54. var aborter;
  55. // allow shortcut if iterator expects only two arguments
  56. if (iterator.length == 2)
  57. {
  58. aborter = iterator(item, async(callback));
  59. }
  60. // otherwise go with full three arguments
  61. else
  62. {
  63. aborter = iterator(item, key, async(callback));
  64. }
  65. return aborter;
  66. }