Conversation
1d27b1e to
4102ef3
Compare
|
I added tests that reveal problems and now it’s clear that we need to change data structure for wrappers. Maybe better store them mixed to functions: |
|
Implemented in a different way. Now we hold AsyncEmitter {
events:
Map {
'eventName' => {
on: Set { listener<Function> },
once: Map { listener<Function> => wrapper<Function> }
},
}
} |
Co-Authored-By: Denys Otrishko <shishugi@gmail.com> Co-Authored-By: Mykola Bilochub <nbelochub@gmail.com> Co-Authored-By: Dmytro Nechai <nechaido@gmail.com>
| const event = this.events.get(name); | ||
| if (!event) return 0; | ||
| const { on, once } = event; | ||
| return on.size + once.size; |
There was a problem hiding this comment.
Nit: can be simplified to:
return event ? event.on.size + event.once.size : 0;| // Get or create event | ||
| // name <string> event name | ||
| // Returns: { on: <Set>, once: <Set> } } | ||
| event(name) { |
There was a problem hiding this comment.
I'd prefer to use Symbol('getListeners') for this, to make this property "private".
|
|
||
| class AsyncEmitter { | ||
| constructor() { | ||
| this.events = new Map(); |
There was a problem hiding this comment.
| this.events = new Map(); | |
| this.listeners = new Map(); |
| if (!event) return Promise.resolve(); | ||
| const { on, once } = event; | ||
| const promises = [...on, ...once].map(fn => fn(...args)); | ||
| once.clear(); |
There was a problem hiding this comment.
I'd prefer to move this one line up, because some of the listeners may create additional once listeners.
| metatests.test('AsyncEmitter on/emit', async test => { | ||
| const ae = new AsyncEmitter(); | ||
|
|
||
| const fn = test.mustCall(async (a, b, c, d) => { |
There was a problem hiding this comment.
?
| const fn = test.mustCall(async (a, b, c, d) => { | |
| const fn = test.mustCall(async (...args) => { test.strictSame(args, [1, 2, 3, 4]) }); |
|
|
||
| metatests.test('AsyncEmitter once', async test => { | ||
| const ae = new AsyncEmitter(); | ||
|
|
There was a problem hiding this comment.
You should add a test, to ensure that emit args are forwarded to once listener.
| once(name, fn) { | ||
| if (fn === undefined) { | ||
| return new Promise(resolve => { | ||
| this.once(name, resolve); |
There was a problem hiding this comment.
| this.once(name, resolve); | |
| this.once(name, (...args) => resolve(args.length <= 1 ? args[0] : args) | |
| ); |
| }); | ||
|
|
||
| setTimeout(fn, 0); | ||
| await ae.once('e1'); |
I suppose we need to hide counters when waiting for multiple event handlers to this abstraction.