| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 | /** * Module dependencies. */try {  var EventEmitter = require('events').EventEmitter;  if (!EventEmitter) throw new Error();} catch (err) {  var Emitter = require('emitter');}/** * Defer. */var defer = typeof process !== 'undefined' && process && typeof process.nextTick === 'function'  ? process.nextTick  : function(fn){ setTimeout(fn); };/** * Noop. */function noop(){}/** * Expose `Batch`. */module.exports = Batch;/** * Create a new Batch. */function Batch() {  if (!(this instanceof Batch)) return new Batch;  this.fns = [];  this.concurrency(Infinity);  this.throws(true);  for (var i = 0, len = arguments.length; i < len; ++i) {    this.push(arguments[i]);  }}/** * Inherit from `EventEmitter.prototype`. */if (EventEmitter) {  Batch.prototype.__proto__ = EventEmitter.prototype;} else {  Emitter(Batch.prototype);}/** * Set concurrency to `n`. * * @param {Number} n * @return {Batch} * @api public */Batch.prototype.concurrency = function(n){  this.n = n;  return this;};/** * Queue a function. * * @param {Function} fn * @return {Batch} * @api public */Batch.prototype.push = function(fn){  this.fns.push(fn);  return this;};/** * Set wether Batch will or will not throw up. * * @param  {Boolean} throws * @return {Batch} * @api public */Batch.prototype.throws = function(throws) {  this.e = !!throws;  return this;};/** * Execute all queued functions in parallel, * executing `cb(err, results)`. * * @param {Function} cb * @return {Batch} * @api public */Batch.prototype.end = function(cb){  var self = this    , total = this.fns.length    , pending = total    , results = []    , errors = []    , cb = cb || noop    , fns = this.fns    , max = this.n    , throws = this.e    , index = 0    , done;  // empty  if (!fns.length) return defer(function(){    cb(null, results);  });  // process  function next() {    var i = index++;    var fn = fns[i];    if (!fn) return;    var start = new Date;    try {      fn(callback);    } catch (err) {      callback(err);    }    function callback(err, res){      if (done) return;      if (err && throws) return done = true, defer(function(){        cb(err);      });      var complete = total - pending + 1;      var end = new Date;      results[i] = res;      errors[i] = err;      self.emit('progress', {        index: i,        value: res,        error: err,        pending: pending,        total: total,        complete: complete,        percent: complete / total * 100 | 0,        start: start,        end: end,        duration: end - start      });      if (--pending) next();      else defer(function(){        if(!throws) cb(errors, results);        else cb(null, results);      });    }  }  // concurrency  for (var i = 0; i < fns.length; i++) {    if (i == max) break;    next();  }  return this;};
 |