codekingpro/portable-devtools
114k
1var async = require('./async.js')2 , abort = require('./abort.js')3 ;4 5// API6module.exports = iterate;7 8/**9 * Iterates over each job object10 *11 * @param {array|object} list - array or object (named list) to iterate over12 * @param {function} iterator - iterator to run13 * @param {object} state - current job status14 * @param {function} callback - invoked when all elements processed15 */16function iterate(list, iterator, state, callback)17{18 // store current index19 var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;20 21 state.jobs[key] = runJob(iterator, key, list[key], function(error, output)22 {23 // don't repeat yourself24 // skip secondary callbacks25 if (!(key in state.jobs))26 {27 return;28 }29 30 // clean up jobs31 delete state.jobs[key];32 33 if (error)34 {35 // don't process rest of the results36 // stop still active jobs37 // and reset the list38 abort(state);39 }40 else41 {42 state.results[key] = output;43 }44 45 // return salvaged results46 callback(error, state.results);47 });48}49 50/**51 * Runs iterator over provided job element52 *53 * @param {function} iterator - iterator to invoke54 * @param {string|number} key - key/index of the element in the list of jobs55 * @param {mixed} item - job description56 * @param {function} callback - invoked after iterator is done with the job57 * @returns {function|mixed} - job abort function or something else58 */59function runJob(iterator, key, item, callback)60{61 var aborter;62 63 // allow shortcut if iterator expects only two arguments64 if (iterator.length == 2)65 {66 aborter = iterator(item, async(callback));67 }68 // otherwise go with full three arguments69 else70 {71 aborter = iterator(item, key, async(callback));72 }73 74 return aborter;75}76 