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