notes on javascript, linux, and more

12.16.2008

A Threading Class for Javascript

Note: please see this post for an updated version of this code.

Most modern programming languages have a Threading class that allows the user to fork from a program's main thread and execute code asynchronously. I have been using Javascript a lot lately, and although it doesn't provide a Threading class or even a Thread.sleep() type of function, it turns out it is not so hard to throw something together using setTimeout and setInterval with anonymous functions.
Thread = function (threadFunction,
threadCompletedFunction,
threadStartedFunction,
threadProgressCallback,
threadProgressCallbackTimeout) {
/* creates a fork off of the main Javascript thread and allows that thread to have callbacks for different states.
Example usage:
var myThread = new Thread( function(){alert('in the main function');},
function(){alert('thread completed');},
function(){alert('thread started ');},
function(){alert('checking progress...');},
500 ); // the progress checking function is looped every 500 ms
myThread.start();
*/

// private variables
var threadProgressCallbackSwitch = true;
var progressCallbackId;

// the progress callback is repeatedly called by setInterval
// so this wrapper is used to allow the loop to exit at some point via clearInterval
var threadProgressCallbackCaller = function() {
threadProgressCallbackSwitch ? threadProgressCallback() : clearInterval(progressCallbackId);
}

// replace undefined parameters with empty functions
if (threadFunction == undefined) threadFunction = function(){}
if (threadCompletedFunction == undefined) threadCompletedFunction = function(){}
if (threadStartedFunction == undefined) threadStartedFunction = function(){}

// define the main thread driver
this.start = function() {
var thread = function () {
if (threadProgressCallback != undefined) {
// if there is a progress checking callback, start looping it
if (threadProgressCallbackTimeout == undefined) threadProgressCallbackTimeout = 300;
progressCallbackId = setInterval(threadProgressCallbackCaller, threadProgressCallbackTimeout);
}
threadStartedFunction();
threadFunction();
threadCompletedFunction();
threadProgressCallbackSwitch = false;
}
setTimeout(thread,0); // initiates the asynchronous call and returns control back to original caller
return;
}
}
Thread.sleep = function (delay){
/* simulates a Thread pause for 'delay' milliseconds
known issues:
while sleeping, browser is non-interactive
some browsers will warn the user that an infinite loop may be in progress
*/
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + delay){}
}

1 comment:

Stewart said...

Interesting post,

Thanks a ton for sharing this useful information and hope to read more from you.

Software Directory

About Me

My photo
chicago, il, United States
I'm a software engineer by profession.

Labels