Hello, just want to ask something that comes to my head.
I’m using a setInterval with 250 ms because I need to update an object that is linked to some dynamic input fields, so need to have a very fast update when any field changes. This object has no callbacks when the value changes so I can’t fire an event when a value is changed.
After a deep testing, this is the only way that I managed to make it works as I want.
So my question is simple: Is setInterval a bad “script”? Can slow down my page?
Regards.
The second option is a round about way of doing the first, so why not just use the first? Why would doing it recursively even be an option to consider?
You usually don’t want to have an interval unconditionally keep running forever, and there’s a slight difference in that respect as with setInterval(), you have to remember the handle if you want to “break” from the loop at some point:
var DELAY = 250
var handle = window.setInterval(function () {
doStuff()
if (breakCondition) {
window.clearInterval(handle)
}
}, DELAY)
window.setTimeout(function loopFn () {
doStuff()
if (!breakCondition) {
window.setTimeout(loopFn, DELAY)
}
}, DELAY)
Personally I prefer the setTimeout() version for that reason, but that’s mostly a matter of preference really… as @mawburn says, using setInterval() would probably be more straight-forward here.
That being said…
Such polling for changes is very dirty and inefficient… in JS it’s quite common to implement your own event system instead (known as the observer patter). Instead of modifying an object directly, you call a method on a subject that maintains the state; and this subject in turn notifies its subscribers of any such changes. Here’s how an implementation might look like:
var createSubject = function (initialState) {
var state = initialState || {}
var subscribers = []
var publish = function () {
var args = arguments
subscribers.forEach(function (subscriber) {
subscriber.apply(this, args)
}, this)
}
return {
subscribe: function (callback) {
if (subscribers.indexOf(callback) === -1) {
subscribers.push(callback)
}
},
unsubscribe: function (callback) {
subscribers = subscribers.filter(function (subscriber) {
return subscriber !== callback
})
},
setItem: function (key, value) {
state[key] = value
publish.call(this, key, value, state)
},
getItem: function (key) {
return state[key]
}
}
}
// Usage:
var observable = createSubject()
observable.subscribe(console.log)
observable.setItem('foo', 'bar') // -> "foo", "bar", { foo: "bar" }
observable.setItem('mol', 42) // -> "mol", "42", { foo: "bar", mol: 42 }