Web workers are great; they provide a powerful way to run background threads on website.
I wanted to create a more convenient way to deal with them in a jQuery-esque way. This code allows you to create a web worker and returns a jQuery.Deferred
extended with some of the web worker methods on the instance.
(function($, undefined){
// Worker method
$.worker = function(args) {
var def = $.Deferred();
if (window.Worker) {
var url = args.file;
// Construct the Web Worker
var worker = new Worker(url);
// If the Worker closes, resolve the Deferred
worker.onclose = function(event) {
def.resolve();
};
// If the Worker posts a message, send a notification
worker.onmessage = function(event) {
def.notifyWith(event);
};
// If the Worker reports an error, reject the Deferred
worker.onerror = function(event) {
def.reject(event);
};
// Create a pointer to 'postMessage' on the Deferred
def.postMessage = function(msg){
worker.postMessage(msg);
};
def.terminate = function(){
worker.terminate();
def.resolve();
};
// If args were passed, start the worker with supplied args
if(args.args){
worker.postMessage(args.args);
}
}
else {
def.reject('No worker support!');
}
return def;
};
})(jQuery);
Now we call it like:
var worker = $.worker({
file: 'test_worker.js',
args: { anArg: "hello!" }
}).then(function(data) {
// Worker completed successfully
}).fail(function(data){
// Worker threw an error
});
Since we attached the postMessage
to the instance of the Deferred we return we can call postMessage
like:
worker.postMessage("monkey");
we can use jQuery.when
like:
var work1 = $.worker(doStuff, {a:1, b:50});
var work2 = $.worker(doStuff, {a:51, b:100});
$.when(work1, work2).then(function(result1, result2){
//success - do something with result1 and result2
}).fail(function(event){
//exception occurred! look at the event argument.
});