-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90ba0ba
commit ca5746a
Showing
1 changed file
with
18 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,37 @@ | ||
// Creating event emitter | ||
|
||
class EventEmitter { | ||
constructor() { | ||
this.subscriptionList = new Map(); | ||
} | ||
|
||
// Subscribe to an event with a callback function | ||
subscribe(eventName, callback) { | ||
const sym = Symbol(); | ||
const id = Symbol(); // Unique identifier for the subscription | ||
if (!this.subscriptionList.has(eventName)) { | ||
const callbackMap = new Map(); | ||
callbackMap.set(sym, callback); | ||
this.subscriptionList.set(eventName, callbackMap); | ||
} else { | ||
const callbackMap = this.subscriptionList.get(eventName); | ||
callbackMap.set(sym, callback); | ||
this.subscriptionList.set(eventName, new Map()); | ||
} | ||
const eventMap = this.subscriptionList.get(eventName); | ||
eventMap.set(id, callback); | ||
|
||
const that = this; // store the reference to the EventEmitter instance | ||
// Return an object with a release method to unsubscribe | ||
return { | ||
release: function releaseFn() { | ||
const list = that.subscriptionList.get(eventName); | ||
list && list.delete(sym); | ||
// Clean up if there are no more subscriptions for the event | ||
if (list && list.size === 0) { | ||
that.subscriptionList.delete(eventName); | ||
release: () => { | ||
// Remove the callback from the event's subscription map | ||
if (eventMap.has(id)) { | ||
eventMap.delete(id); | ||
} | ||
// If there are no more subscribers, remove the event entry | ||
if (eventMap.size === 0) { | ||
this.subscriptionList.delete(eventName); | ||
} | ||
}, | ||
}; | ||
} | ||
|
||
// Emit an event with optional arguments | ||
emit(eventName, ...args) { | ||
const subscriptions = this.subscriptionList.get(eventName); | ||
if (subscriptions) { | ||
subscriptions.forEach((callback) => { | ||
callback(...args); | ||
}); | ||
const eventMap = this.subscriptionList.get(eventName); | ||
if (eventMap) { | ||
eventMap.forEach((cb) => cb.apply(this, args)); // Call each callback with the provided arguments | ||
} | ||
} | ||
} | ||
|
||
// Test cases | ||
|
||
const emitter = new EventEmitter(); | ||
|
||
// Test case: release() should work spec | ||
const sub1 = emitter.subscribe('test', () => console.log('test1')); | ||
sub1.release(); | ||
emitter.emit('test'); // expects no output | ||
|
||
// Test case: release() should work for multiple listeners on the same event spec | ||
const sub2 = emitter.subscribe('test', () => console.log('test2')); | ||
const sub3 = emitter.subscribe('test', () => console.log('test3')); | ||
sub2.release(); | ||
emitter.emit('test'); // expects 'test3' output |