There is a common pattern to implement an observer/event emitter that returns a subscription handler when a new listener is created. This means subscription handler has direct access to the scope that create the listener. Usually, these observers use arrays or sets to store a list of listeners. Removing a listener means using deletion methods that an array or a set provides. Alternatively, the list of listeners can be implemented as a doubly-linked list. This makes both listener insert and delete operations O(1) instead of array/set's complexity. Obviously, there won't be significant performance gain, but no overhead is better than small overhead.
Last active
February 10, 2021 19:16
-
-
Save alexeyraspopov/e579c0ecc565b800594354f5c9649ac5 to your computer and use it in GitHub Desktop.
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
export default class Signal { | |
head = null; | |
tail = null; | |
subscribe(callback) { | |
let listener = { callback, prev: null, next: null }; | |
if (this.head == null) { | |
this.head = listener; | |
this.tail = listener; | |
} else { | |
listener.prev = this.tail; | |
this.tail.next = listener; | |
this.tail = listener; | |
} | |
return { | |
dispose: () => { | |
if (listener === this.head) { | |
this.head = this.head.next; | |
if (this.head != null) { | |
this.head.prev = null; | |
} | |
if (listener === this.tail) { | |
this.tail = null; | |
} | |
} else if (listener === this.tail) { | |
this.tail = this.tail.prev; | |
this.tail.next = null; | |
} else { | |
listener.prev.next = listener.next; | |
listener.next.prev = listener.prev; | |
} | |
}, | |
}; | |
} | |
publish(data) { | |
let cursor = this.head; | |
while (cursor != null) { | |
cursor.callback.call(null, data); | |
cursor = cursor.next; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment