Skip to content

Instantly share code, notes, and snippets.

@benlesh
Last active August 29, 2015 14:06
Show Gist options
  • Save benlesh/af4e80adb5de7f9e4504 to your computer and use it in GitHub Desktop.
Save benlesh/af4e80adb5de7f9e4504 to your computer and use it in GitHub Desktop.
dynamic-worker-blog-entry
describe('Muppet worker script', function(){
var muppet, mockGlobal;
beforeEach(function(){
// we don't want to actually start a worker
// so let's give it a dummy worker that doesn't do anything.
var DummyWorker = function() {};
var muppet = new Muppet(DummyWorker);
// mock the global scope for the worker thread.
var mockGlobal = {
postMessage: jasmine.createSpy('postMessage');
};
// call the initWorker method we use to build the worker script.
muppet.initWorker(mockGlobal);
});
it('should tell you when it is ready', function(){
expect(mockGlobal.postMessage).toHaveBeenCalledWith('I am ready');
});
it('should respond properly to mnah mnah', function() {
mockGlobal.onmessage('mnah mnah');
expect(mockGlobal.postMessage).toHaveBeenCalledWith('doot doo do-do-do');
});
it('should get confused about other phrases', function() {
mockGlobal.onmessage('blah');
expect(mockGlobal.postMessage).toHaveBeenCalledWith('huh?');
});
});
var muppet = new Muppet();
muppet.says(function(phrase) {
console.log(phrase);
});
muppet.tell('mnah mnah');
// console: "doot doo do-do-do"
muppet.tell('what?');
// console: "huh?"
/**
* A simple class that creates another thread that responds to silly messages
* with other silly messages. Okay, really it only knows 'mnah mnah'
* @class Muppet
* @constructor
* @param Worker {Worker} injection point for Worker
*/
function Muppet(Worker) {
Worker = Worker || window.Worker;
this.url = this.getWorkerURL();
this.worker = new Worker(this.url);
}
Muppet.prototype = {
// get the worker script in string format.
getWorkerScript: function(){
var js = '';
js += '(' + this.workerInit + ')(this);';
return js;
},
// This function really represents the body of our worker script.
// The global context of the worker script will be passed in.
workerInit: function(global) {
global.onmessage = function(e) {
var response = e.data === 'mnah mnah' ? 'doot doo do-do-do' : 'huh?';
global.postMessage(response);
};
global.postMessage('I am ready');
},
// get a blob url for the worker script from the worker script text
getWorkerURL: function() {
var blob = new Blob([this.getWorkerScript()], { type: 'text/javascript' });
return URL.createObjectURL(blob);
},
// kill the muppet. Sick, just sick.
kill: function() {
if(this.worker) {
this.worker.terminate();
}
if(this.url) {
URL.revokeObjectURL(this.url);
}
},
// say something to the muppet
tell: function(msg) {
if(this.worker) {
this.worker.postMessage(msg);
}
},
// listen for the muppet to talk back
says: function(handler) {
if(this.worker) {
this.worker.addEventListener('message', function(e) {
handler(e.data);
});
}
},
};
// teardown
worker.terminate();
URL.revokeObjectURL(url);
var js = 'postMessage ("hello from the worker!");';
var blob = new Blob([js], { type: 'text/javascript' });
var url = URL.createObjectURL(blob);
var worker = new Worker(url);
worker.onmessage = function(e) {
console.log(e.data);
};
var worker = new Worker('myworkerscript.js');
worker.onmessage = function(e) {
console.log('the worker said: ' + e.data);
};
worker.postMessage('mnah mnah');
onmessage = function(e) {
console.log('the window said: ' + e.data);
postMessage('doot doo do-do-do');
}
postMessage('I am totally loaded.');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment