53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
|
export class AsyncEmitter {
|
||
|
async emitAsync(event: string | symbol, ...args: any[]): Promise<boolean> {
|
||
|
// @ts-ignore
|
||
|
const events = this._events;
|
||
|
let callbacks = events[event];
|
||
|
if (!callbacks) {
|
||
|
return false;
|
||
|
}
|
||
|
// helper function to reuse as much code as possible
|
||
|
const run = (cb) => {
|
||
|
switch (args.length) {
|
||
|
// fast cases
|
||
|
case 0:
|
||
|
cb = cb.call(this);
|
||
|
break;
|
||
|
case 1:
|
||
|
cb = cb.call(this, args[0]);
|
||
|
break;
|
||
|
case 2:
|
||
|
cb = cb.call(this, args[0], args[1]);
|
||
|
break;
|
||
|
case 3:
|
||
|
cb = cb.call(this, args[0], args[1], args[2]);
|
||
|
break;
|
||
|
// slower
|
||
|
default:
|
||
|
cb = cb.apply(this, args);
|
||
|
}
|
||
|
|
||
|
if (cb && (cb instanceof Promise || typeof cb.then === 'function')) {
|
||
|
return cb;
|
||
|
}
|
||
|
|
||
|
return Promise.resolve(true);
|
||
|
};
|
||
|
|
||
|
if (typeof callbacks === 'function') {
|
||
|
await run(callbacks);
|
||
|
} else if (typeof callbacks === 'object') {
|
||
|
callbacks = callbacks.slice().filter(Boolean);
|
||
|
await callbacks.reduce((prev, next) => {
|
||
|
return prev.then((res) => {
|
||
|
return run(next).then((result) =>
|
||
|
Promise.resolve(res.concat(result)),
|
||
|
);
|
||
|
});
|
||
|
}, Promise.resolve([]));
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|