Skip to content
Snippets Groups Projects
index.js 1.08 KiB
Newer Older
  • Learn to ignore specific revisions
  • Andrew Kelley's avatar
    Andrew Kelley committed
    module.exports = Pend;
    
    function Pend() {
      this.pending = 0;
    
      this.max = Infinity;
    
    Andrew Kelley's avatar
    Andrew Kelley committed
      this.listeners = [];
    
    Andrew Kelley's avatar
    Andrew Kelley committed
      this.error = null;
    }
    
    Pend.prototype.go = function(fn) {
    
      if (this.pending < this.max) {
        pendGo(this, fn);
      } else {
        this.waiting.push(fn);
      }
    
    Andrew Kelley's avatar
    Andrew Kelley committed
    };
    
    Pend.prototype.wait = function(cb) {
      if (this.pending === 0) {
        cb(this.error);
      } else {
        this.listeners.push(cb);
      }
    };
    
    
    Andrew Kelley's avatar
    Andrew Kelley committed
    Pend.prototype.hold = function() {
      return pendHold(this);
    };
    
    function pendHold(self) {
    
    Andrew Kelley's avatar
    Andrew Kelley committed
      self.pending += 1;
    
      var called = false;
    
    Andrew Kelley's avatar
    Andrew Kelley committed
      return onCb;
    
    Andrew Kelley's avatar
    Andrew Kelley committed
      function onCb(err) {
    
        if (called) throw new Error("callback called twice");
        called = true;
    
    Andrew Kelley's avatar
    Andrew Kelley committed
        self.error = self.error || err;
        self.pending -= 1;
    
        if (self.waiting.length > 0 && self.pending < self.max) {
          pendGo(self, self.waiting.shift());
        } else if (self.pending === 0) {
    
          var listeners = self.listeners;
    
    Andrew Kelley's avatar
    Andrew Kelley committed
          self.listeners = [];
    
          listeners.forEach(cbListener);
    
    Andrew Kelley's avatar
    Andrew Kelley committed
        }
      }
      function cbListener(listener) {
        listener(self.error);
      }
    }
    
    Andrew Kelley's avatar
    Andrew Kelley committed
    
    function pendGo(self, fn) {
      fn(pendHold(self));
    }