-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathc-async.js
More file actions
118 lines (99 loc) · 2.26 KB
/
c-async.js
File metadata and controls
118 lines (99 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'use strict';
class AsyncEmitter {
constructor() {
this.events = new Map();
}
event(name) {
let event = this.events.get(name);
if (event) return event;
const on = new Set();
const once = new Set();
event = { on, once };
this.events.set(name, event);
return event;
}
on(name, fn) {
this.event(name).on.add(fn);
}
once(name, fn) {
if (fn === undefined) {
return new Promise((resolve) => {
this.once(name, resolve);
});
}
this.event(name).once.add(fn);
return null;
}
async emit(name, ...args) {
const event = this.events.get(name);
if (!event) return null;
const { on, once } = event;
const aon = [...on.values()];
const aonce = [...once.values()];
const promises = aon.concat(aonce).map((fn) => fn(...args));
once.clear();
if (on.size === 0 && once.size === 0) {
this.events.delete(name);
}
return Promise.all(promises);
}
remove(name, fn) {
const { events } = this;
const event = events.get(name);
if (!event) return;
const { on, once } = event;
on.delete(fn);
once.delete(fn);
if (on.size === 0 && once.size === 0) {
this.events.delete(name);
}
}
clear(name) {
const { events } = this;
if (!name) {
events.clear();
return;
}
const event = events.get(name);
if (event) events.delete(name);
}
count(name) {
const event = this.events.get(name);
if (!event) return 0;
const { on, once } = event;
return on.size + once.size;
}
listeners(name) {
const event = this.events.get(name);
if (!event) return [];
const { on, once } = event;
return [...on.values(), ...once.values()];
}
names() {
return [...this.events.keys()];
}
}
// Usage
const main = async () => {
const ee = new AsyncEmitter();
ee.on('e1', async () => {
console.log('e1 listener 1');
});
ee.on('e1', async () => {
console.log('e1 listener 2');
});
ee.on('e1', async () => {
console.log('e1 listener 3');
});
ee.on('e2', async () => {
console.log('e2 listener 1');
});
ee.on('e2', async () => {
console.log('e2 listener 2');
});
console.log('begin');
await ee.emit('e1');
await ee.emit('e2');
console.log('end');
};
main();