The web application development framework provides the following constructs for your convenience. [Templating] will rely on these types to enable automatically updated data content.
class Observable {
constructor(initialValue) {
this.listeners = []
this.currentValue = initialValue
}
onSet(listener) {
this.listeners.push(listener)
return this.listeners.length - 1
}
removeSetListener(i) {
delete this.listeners[i]
}
get value() {
return this.currentValue
}
set value(newValue) {
var oldValue = this.currentValue
this.currentValue = newValue
for (var i in this.listeners) {
var listener = this.listeners[i]
if (typeof listener === "function") {
var live = listener(newValue, oldValue, this)
if (!live) {
delete this.listeners[i]
}
}
}
}
}
class Polling {
constructor(msec) {
this.msec = msec
this.timer = null
this.listeners = []
}
emit() {
for (var i in listeners) {
var listener = this.listeners[i]
if (typeof listener === "function") {
var live = listener()
if (!live) {
delete this.listeners[i]
}
}
}
}
polled(getter) {
if (!this.timer) {
this.timer = setInterval(this.emit, this.msec)
}
var rv = new Observable(getter())
this.listeners.push(() => {
let newValue = getter()
if (rv.value !== newValue) {
rv.value = newValue
}
return true
})
return rv
}
}
var secondly25times = new Polling(40)
var secondly = new Polling(1000)
var minutely = new Polling(60000)
Wiki: Home
Wiki: Polite Callbacks
Wiki: Templating
E.g. the clock as an Observable:
The callback will be called secondly once, because the toString() keeps returning the same until the second hand of the clock ticks. It updates no later than 40 milliseconds after the second really begins.
To make it less CPU-consuming, you can give up on accuracy (can update a whole second later than the beginning of that second, but contains microsecond info.)
observable = secondly.polled(() => new Date())
Last edit: Csaba Skrabák 2024-04-03