I read this implementation of an event emitter on LeetCode and wanted to ask a few questions.
release method in the return of the subscribe method? Why can't I make it its own method?unsubscribe method like this and how would I use it if it was its own method?subscriptions variable defined in a constructor?Thank you.
class EventEmitter {
subscriptions = new Map()
subscribe(eventName, callback) {
if (!this.subscriptions.has(eventName)) {
this.subscriptions.set(eventName, new Set())
}
const newSub = { callback }
this.subscriptions.get(eventName).add(newSub)
return {
unsubscribe: () => {
const evSub = this.subscriptions.get(eventName)
evSub.delete(newSub)
if (evSub.size === 0)
this.subscriptions.delete(eventName)
}
}
}
emit(eventName, ...args) {
const callbacks = this.subscriptions.get(eventName)
if (!callbacks) return
for (let c of callbacks) {
c.callback(...args)
}
}
}
Answer 1: In case unsubscribing needs information only available from making the subscription (like a subscription eventName) it makes sense to provide the function directly from the creation. It saves you having to store data needed in the unsubscription process in some intermediary form. You can make it is own method if you want, but still need to return it as in this code:
unsubscribe(eventName) => {
const evSub = this.subscriptions.get(eventName)
evSub.delete(newSub)
if (evSub.size === 0)
this.subscriptions.delete(eventName)
}
subscribe(eventName, callback) {
if (!this.subscriptions.has(eventName)) {
this.subscriptions.set(eventName, new Set())
}
const newSub = { callback }
this.subscriptions.get(eventName).add(newSub)
return () => unsubscribe(eventName);
}
Answer 2: You store the return value from subscribe some place you can access it, then invoke it if needed by calling unsubscribe(). How it's used is not different whether it's in its own function or not. It still needs to know the eventName so you need the one returned from subscribe. Like in this code:
const unsub = subscribe("event1", () => {});
// then later
unsub(); // unsubscribe from event1
Answer 3: There's nothing wrong with it. It's a design choice.
Answer 4: That's personal choice.
Answer 5: I assume you're asking about subscriptions variable (plural) and not the subscription function. It's defined as a class variable which doesn't need any initialization specific to a ctor parameter so there's no need to make one. You could put it in a ctor if you wanted to but it just makes the code longer without any real benefit. If the ctor took in some parameters that would affect the initial value of subscriptions then it could be done in the ctor.