index.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. module.exports = Pend;
  2. function Pend() {
  3. this.pending = 0;
  4. this.max = Infinity;
  5. this.listeners = [];
  6. this.waiting = [];
  7. this.error = null;
  8. }
  9. Pend.prototype.go = function(fn) {
  10. if (this.pending < this.max) {
  11. pendGo(this, fn);
  12. } else {
  13. this.waiting.push(fn);
  14. }
  15. };
  16. Pend.prototype.wait = function(cb) {
  17. if (this.pending === 0) {
  18. cb(this.error);
  19. } else {
  20. this.listeners.push(cb);
  21. }
  22. };
  23. Pend.prototype.hold = function() {
  24. return pendHold(this);
  25. };
  26. function pendHold(self) {
  27. self.pending += 1;
  28. var called = false;
  29. return onCb;
  30. function onCb(err) {
  31. if (called) throw new Error("callback called twice");
  32. called = true;
  33. self.error = self.error || err;
  34. self.pending -= 1;
  35. if (self.waiting.length > 0 && self.pending < self.max) {
  36. pendGo(self, self.waiting.shift());
  37. } else if (self.pending === 0) {
  38. var listeners = self.listeners;
  39. self.listeners = [];
  40. listeners.forEach(cbListener);
  41. }
  42. }
  43. function cbListener(listener) {
  44. listener(self.error);
  45. }
  46. }
  47. function pendGo(self, fn) {
  48. fn(pendHold(self));
  49. }