Split ImmediateSpeaker into separate class

This commit is contained in:
Talia 2021-11-25 10:37:16 +01:00
parent 738d6ca493
commit cabf557569
2 changed files with 41 additions and 31 deletions

View file

@ -1,43 +1,47 @@
class Speaker { export class Speaker {
#callbacks = new Set() _callbacks = new Set()
#immediate _scheduled = []
#scheduled = [] _retain
#retain
constructor(immediate, ...initial) { constructor(...initial) {
this.#immediate = immediate this._retain = initial
this.#retain = initial
} }
listen(callback) { listen(callback) {
this.#callbacks.add(callback) this._callbacks.add(callback)
return this.#retain return this._retain
} }
speak(...args) { speak(...args) {
if (this.#immediate) { if (!this._scheduled.length) {
for (let callback of this.#callbacks) {
callback(...args)
}
this.#retain = args
} else {
if (!this.#scheduled.length) {
queueMicrotask(() => { queueMicrotask(() => {
for (let args of this.#scheduled) { for (let args of this._scheduled) {
for (let callback of this.#callbacks) { for (let callback of this._callbacks) {
callback(...args) callback(...args)
} }
this.#retain = args this._retain = args
} }
this.#scheduled = [] this._scheduled = []
}) })
} }
this.#scheduled.push(args) this._scheduled.push(args)
}
} }
silence(callback) { forget(callback) {
this.#callbacks.delete(callbacks) this._callbacks.delete(callbacks)
}
silence() {
this._callbacks.clear()
}
}
export class ImmediateSpeaker extends Speaker {
speak(...args) {
for (let callback of this._callbacks) {
callback(...args)
}
this._retain = args
} }
} }

View file

@ -6,7 +6,7 @@ Callbacks are scheduled as microtasks by default.
## Interface: ## Interface:
``` ```
Speaker(immediate=false, ...initial) Speaker(...initial)
// Creates a new speaker. // Creates a new speaker.
Speaker.listen(callback) Speaker.listen(callback)
// Registers a callback. // Registers a callback.
@ -24,7 +24,7 @@ first call to `speak`.
A simple example: A simple example:
```js ```js
const speaker = new Speaker(true /* run callbacks immediately */) const speaker = new Speaker()
speaker.listen(value => console.log(value)) speaker.listen(value => console.log(value))
speaker.listen(value => console.warn(value)) speaker.listen(value => console.warn(value))
@ -64,3 +64,9 @@ defer(() => {
defer(() => console.log("This message will appear last")) defer(() => console.log("This message will appear last"))
}) })
``` ```
## ImmediateSpeaker
This class may likely be renamed in the future.
Extends the speaker class, but doesn't defer its callbacks to a mycrotask.