Pesudo Threading in JavaScript: Watch what you're doing
I was working on some debugging and I wanted to do some logging of some variables that were going through numerous changes. However I didn't want to be littering my code with all the debug/logging code, you just know that I'd leave some of it in and cause me to do more searching and potentially have additional errors down the road.
Anyway, I ended up using the JavaScript object watch method when working with simple values by adding the watch to the parent object. This allowed me to keep my debugging/logging code in just a couple of places. The watch method also allows you to perform data validation by intercepting changes to values.
A basic example:
// Basic logger object
function Logger(){
this.loggedItems = [];
this.logItem = function(itemToLog){
this.loggedItems.push(itemToLog);
}
this.showLog = function(){
alert(this.loggedItems.join('\n'));
}
}
// Create an instance of the logger object
var myLog = new Logger();
// Basic object
function Person(){
this.age = 0;
// add watch on age property
this.watch('age',
function(prop, oldVal, newVal){
myLog.logItem('setting ' + prop + ' to ' + newVal);
return newVal;
}
);
}
// Create new object
var p = new Person();
// set value
p.age = 80;
// drink from the fountain of youth
p.age = 70;
p.age = 60;
p.age = 50;
// Let's see that log
myLog.showLog();
// result:
// setting age to 80
// setting age to 70
// setting age to 60
// setting age to 50
So what this does is to react any time that age is changed. So when age is changed, a function intercepts that change and is passed three parameters, the name of the property that was watched, the old value of the property, and then the new value of the property. This function then returns the value that will be used as the value that is actually assigned to the property when it is changed. In this example, we aren't doing any validation (you know a person can't be -12 years old right?), so we could check the value and if it isn't a valid value being assigned to the property, then we can return the old value and effectively not make any change to the property.
What we are doing instead is logging the new value. This allows us to track the changes to this property as the application runs. In this simple example, we just just show the log after a couple of changes. You could expand this to more of your simple value properties.
When I'm done debugging I just pull the code from the parent objects rather than from many places within the application. Still prone to leaving in some logging code, but it seems less so than logging at every point the property is changed.
A caveat: Changes to an object or adding an element to an array aren't handled with the watch method as the "value" of the property being watched isn't changing, that is, the array contents are changing, but it's still that same array, and it's the array that is being watched, not the contents of the array, same thing with an object.
Of course there are other ways to log and may be some better ways to add the logging in that would even further limit any issues when the debugging is over, but I just wanted to get across the basic usage of the watch method.
So what's with the "pseduo threading" in the post title? Well that is basically from the processing that occurs, it steps through executing each line as it reaches it, until the assignment of the watched property, the processing then breaks off to the function passed into the watch method, does what ever processing needed, then execution picks up where it left off on the next line after the property assignment. So it's sorta "threaded" in that the other code gets executed without being directly called in the code, but it's pseduo in that it's actually executed inline.
Alright, I think that's enough rambling for now.
Labels: JavaScript, watch

