Reputation: 35
I have a script that uses setInterval
to check for some object state, but it cause a little bit of lag and I was wondering whether I could use an MutationObserver
?
My setInterval
:
var checkExist = setInterval(function() {
var life = 300;
var games = Game.currentGame.ui.playerPetTick.health;
if (games < life) {
console.log("It exists")
clearInterval(checkExist);
}
}, 100); // check every 100ms
My observer attempt:
var target = Game.currentGame.ui.playerPetTick.health;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.info("It exists");
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
Could this be done?
Upvotes: 2
Views: 599
Reputation: 11000
I suggest to use setters and getters (MutationObserver, as I wrote in comment is used only for Node objects). And because property as I assume from your code, might be of various types (object, string, etc.) I suggest to use lodash isEqual
method - it accepts arrays, objects, strings, numbers, etc. so you don't need to write compare function for every type. Very handy function.
You can also install only this particular function.
Here I made a function where you can pass your object and property name to be watched for changes:
var isEqual = require('lodash.isequal');
function watchChanges(object, prop, primaryValue) {
object[`_${prop}`] = primaryValue;
Object.defineProperty(object, prop, {
get() { return object[`_${prop}`] },
set(newValue) {
if ( !isEqual(object[`_${prop}`] , newValue)) {
console.log('change maded in prop')
}
object[`_${prop}`] = newValue;
},
});
}
To inspect what happens, here is an equivalent function for primitive types:
function watchChanges(object, prop, defaultValue) {
object[`_${prop}`] = defaultValue;
Object.defineProperty(object, prop, {
get() { return object[`_${prop}`] },
set(newValue) {
if ( object[`_${prop}`] !== newValue) {
console.log('change maded in', prop, 'was', object[`_${prop}`], 'is', newValue)
}
object[`_${prop}`] = newValue;
},
});
}
ob = {a: 1, b:1, c:1};
watchChanges(ob, 'a', ob.a);
ob.a = 2;
ob.a = 3;
Upvotes: 1
Reputation: 1797
The MutationObserver won't help you here, since your object does not seem to be a DOM node. But you can easily implement some kind of object observing using getters/setters or proxy objects. A simple example:
var playerInfo = {
set health(newValue) {
this._health = newValue;
if (this.onhealthchange) {
this.onhealthchange(newValue);
}
},
get health() {
return this._health;
}
};
playerInfo.onhealthchange = function(newValue) {
console.info("Health changed: " + newValue);
};
playerInfo.health = 4;
Upvotes: 1