Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Created October 4, 2012 13:37
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save amcdnl/3833571 to your computer and use it in GitHub Desktop.
Save amcdnl/3833571 to your computer and use it in GitHub Desktop.
Web Workers and jQuery

Web workers and jQuery

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.

// Alias vendor prefixes to standard.
if (!window.BlobBuilder) {
	window.BlobBuilder = window.WebKitBlobBuilder || window.MozBlobBuilder;
}

if (!window.URL) {
	window.URL = window.webkitURL || window.mozURL;
}
	
$.worker = function(args) { 
	var def = $.Deferred(function(dfd) {
		var worker;
		if (window.Worker) {
			var url = args.file;

			// If we have found a DOM object related,
			// we need constructo a `BlobBuilder` to
			// inline the web worker.
			if(args.id){
				var dom = document.querySelector('#' + args.id),
					blob = new BlobBuilder();

				blob.append(dom.textContent);
				url = window.URL.createObjectURL(blob.getBlob());
			}

			// Construct the Web Worker
			var worker = new Worker(url); 

			// If the Worker reports success, resolve the Deferred
			worker.onmessage = function(event) {			
				dfd.resolve(event); 
			};

			// If the Worker reports an error, reject the Deferred
			worker.onerror = function(event) {
				dfd.reject(event); 
			};

			// Create a pointer to 'postMessage' on the Deferred
			this.postMessage = function(msg){
				worker.postMessage(msg);
			};

			this.terminate = function(){
				worker.terminate();
			};

			// If args were passed, start the worker with supplied args
			if(args.args){
				worker.postMessage(args.args); 
			}
		}
	});

	return def; 
};

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.
});

Inline workers are also supported by this, like so:

<script id="worker" type="app/worker">
	// Web worker code here
</script>

$.worker({ 
	id: 'worker', 
	args: { anArg: "hello!" }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment