matthewrobb
7/25/2014 - 3:37 PM

InlineWorker.js

(function(global){
    "use strict";
    
    function fnToBlob(fn) {
        var body = (fn && fn.toString()) || "";
        return new Blob([ body.slice(body.indexOf("{") + 1, body.length - 1) ]);
    }

    function createWorker(fn) {
        var blobURL = global.URL.createObjectURL(fnToBlob(fn)),
            worker  = new Worker(blobURL),
            listeners, wrapper;
    
        worker.onmessage = function() {
            var list = listeners,
                len  = list && list.length || 0,
                idx  = 0;

            for(var fn; idx < len && (fn = list[idx]); idx++) {
                fn.apply(wrapper, arguments);
            }
        };

        return (wrapper = {
            addListener: function(fn) {
                ~(listeners || (listeners = [])).indexOf(fn) || listeners.push(fn);
                return fn;
            },
        
            removeListener: function(fn) {
                var idx = listeners && listeners.indexOf(fn);
                listsners && ~idx && listeners.splice(idx, 1);
                return fn;
            },
        
            send: function() {
                worker && worker.postMessage.apply(worker, arguments);
            },
        
            release: function() {
                worker = listeners = wrapper = null;
                global.URL.revokeObjectURL(blobURL);
            },
        });
    }
    
    global.createWorker = createWorker;

}).call(this, this);

var worker = createWorker(function() {
    onmessage = function() {
        postMessage("IM A WORKER");
    }
});

worker.addListener(function(e) {
    console.log("A message from a worker: " + e.data);
});

worker.send("Sup");

// MAKE SURE TO DO THIS WHEN FINISHED WITH A WORKER!
// worker.release();