fix: async handling for events

There were issues with async handling in events which can make it
difficult to use event handlers to mutate values provided by an emitter.

This is not an optimal solution: this will await event listeners in
sequence. Ideally, event listeners should be awaited concurrently.
This commit is contained in:
KernelDeimos
2025-04-02 12:43:17 -04:00
parent 1f7073ef76
commit d0edb2c1f3
2 changed files with 11 additions and 10 deletions
+6 -5
View File
@@ -89,15 +89,16 @@ class ExtensionService extends BaseService {
// Propagate all events not from extensions to `core.`
const svc_event = this.services.get('event');
svc_event.on_all((key, data, meta = {}) => {
svc_event.on_all(async (key, data, meta = {}) => {
meta.from_outside_of_extension = true;
this.state.extension.emit(`core.${key}`, data, meta);
await this.state.extension.emit(`core.${key}`, data, meta);
});
this.state.extension.on_all((key, data, meta) => {
this.state.extension.on_all(async (key, data, meta) => {
if ( meta.from_outside_of_extension ) return;
svc_event.emit(key, data, meta);
await svc_event.emit(key, data, meta);
});
this.state.extension.kv = (() => {
+5 -5
View File
@@ -32,8 +32,8 @@ class ScopedEventBus {
this.scope = scope;
}
emit (key, data) {
this.event_bus.emit(this.scope + '.' + key, data);
async emit (key, data) {
await this.event_bus.emit(this.scope + '.' + key, data);
}
on (key, callback) {
@@ -62,7 +62,7 @@ class EventService extends BaseService {
this.global_listeners_ = [];
}
emit (key, data, meta) {
async emit (key, data, meta) {
meta = meta ?? {};
const parts = key.split('.');
for ( let i = 0; i < parts.length; i++ ) {
@@ -76,7 +76,7 @@ class EventService extends BaseService {
for ( const callback of listeners ) {
// IIAFE wrapper to catch errors without blocking
// event dispatch.
Context.arun(async () => {
await Context.arun(async () => {
try {
await callback(key, data, meta);
} catch (e) {
@@ -103,7 +103,7 @@ class EventService extends BaseService {
* @param {Object} [meta={}] - Optional metadata related to the event.
* @returns {void}
*/
Context.arun(async () => {
await Context.arun(async () => {
try {
await callback(key, data, meta);
} catch (e) {