diff --git a/JavaScript/event-aggregation.js b/JavaScript/event-aggregation.js index ce9c63b..de95642 100644 --- a/JavaScript/event-aggregation.js +++ b/JavaScript/event-aggregation.js @@ -3,36 +3,42 @@ const { EventEmitter } = require('node:events'); class Point { + static #bus = new EventEmitter(); + #x; #y; + #id; - constructor({ x, y }, emitter) { + constructor({ x, y }) { this.#x = x; this.#y = y; + this.#id = Symbol('point'); - emitter.on('move', ({ x, y }) => { + Point.#bus.on(`move:${this.#id.description}`, ({ x, y }) => { this.#x += x; this.#y += y; + return this; }); - emitter.on('clone', (callback) => { - const point = new Point({ x: this.#x, y: this.#y }, emitter); - callback(point); - }); + Point.#bus.on(`clone:${this.#id.description}`, () => new Point({ x: this.#x, y: this.#y })); - emitter.on('toString', (callback) => { - callback(`(${this.#x}, ${this.#y})`); - }); + Point.#bus.on(`toString:${this.#id.description}`, () => `(${this.#x}, ${this.#y})`); + } + + emit(type, payload) { + const listener = Point.#bus.listeners(`${type}:${this.#id.description}`)[0]; + if (!listener) throw new Error(`Unknown event: ${type}`); + return listener(payload); } } // Usage -const emitter = new EventEmitter(); -const p1 = new Point({ x: 10, y: 20 }, emitter); -emitter.emit('toString', console.log); -emitter.emit('clone', (c0) => { - emitter.emit('toString', console.log); - emitter.emit('move', { x: -5, y: 10 }); - emitter.emit('toString', console.log); -}); +const p1 = new Point({ x: 10, y: 20 }); +console.log(p1.emit('toString')); + +const c1 = p1.emit('clone'); +console.log(c1.emit('toString')); + +c1.emit('move', { x: -5, y: 10 }); +console.log(c1.emit('toString')); diff --git a/JavaScript/event-compose.js b/JavaScript/event-compose.js index 2b9ccbf..ad2a07f 100644 --- a/JavaScript/event-compose.js +++ b/JavaScript/event-compose.js @@ -5,34 +5,37 @@ const { EventEmitter } = require('node:events'); class Point { #x; #y; + #emitter; constructor({ x, y }) { this.#x = x; this.#y = y; - this.emitter = new EventEmitter(); + this.#emitter = new EventEmitter(); - this.emitter.on('move', ({ x, y }) => { + this.#emitter.on('move', ({ x, y }) => { this.#x += x; this.#y += y; }); - this.emitter.on('clone', (callback) => { - const point = new Point({ x: this.#x, y: this.#y }); - callback(point); - }); + this.#emitter.on('clone', () => new Point({ x: this.#x, y: this.#y })); - this.emitter.on('toString', (callback) => { - callback(`(${this.#x}, ${this.#y})`); - }); + this.#emitter.on('toString', () => `(${this.#x}, ${this.#y})`); + } + + emit(eventName, arg) { + const listener = this.#emitter.listeners(eventName)[0]; + if (!listener) throw new Error(`Unknown event: ${eventName}`); + return listener(arg); } } // Usage const p1 = new Point({ x: 10, y: 20 }); -p1.emitter.emit('toString', console.log); -p1.emitter.emit('clone', (c1) => { - c1.emitter.emit('toString', console.log); - c1.emitter.emit('move', { x: -5, y: 10 }); - c1.emitter.emit('toString', console.log); -}); +console.log(p1.emit('toString')); + +const c1 = p1.emit('clone'); +console.log(c1.emit('toString')); + +c1.emit('move', { x: -5, y: 10 }); +console.log(c1.emit('toString')); diff --git a/JavaScript/event-target.js b/JavaScript/event-target.js index ec7cc86..27fd4cd 100644 --- a/JavaScript/event-target.js +++ b/JavaScript/event-target.js @@ -4,46 +4,50 @@ class PointEvent extends Event { constructor(type, detail = {}) { super(type); this.detail = detail; + this.result = undefined; } } class Point { #x; #y; + #target; constructor({ x, y }) { this.#x = x; this.#y = y; - this.target = new EventTarget(); + this.#target = new EventTarget(); - this.target.addEventListener('move', (event) => { - const { x: dx, y: dy } = event.detail; + this.#target.addEventListener('move', (e) => { + const { x: dx, y: dy } = e.detail; this.#x += dx; this.#y += dy; + e.result = this; }); - this.target.addEventListener('clone', (event) => { - event.detail.callback(new Point({ x: this.#x, y: this.#y })); + this.#target.addEventListener('clone', (e) => { + e.result = new Point({ x: this.#x, y: this.#y }); }); - this.target.addEventListener('toString', (event) => { - event.detail.callback(`(${this.#x}, ${this.#y})`); + this.#target.addEventListener('toString', (e) => { + e.result = `(${this.#x}, ${this.#y})`; }); } emit(type, detail = {}) { - this.target.dispatchEvent(new PointEvent(type, detail)); + const event = new PointEvent(type, detail); + this.#target.dispatchEvent(event); + return event.result; } } // Usage const p1 = new Point({ x: 10, y: 20 }); -p1.emit('toString', { callback: console.log }); -p1.emit('clone', { - callback: (c1) => { - c1.emit('toString', { callback: console.log }); - c1.emit('move', { x: -5, y: 10 }); - c1.emit('toString', { callback: console.log }); - }, -}); +console.log(p1.emit('toString')); + +const c1 = p1.emit('clone'); +console.log(c1.emit('toString')); + +c1.emit('move', { x: -5, y: 10 }); +console.log(c1.emit('toString'));