Ben Dilts Ben Dilts - 7 months ago 54
Javascript Question

Web workers without a separate Javascript file?

As far as I can tell, web workers need to be written in a separate JavaScript file, and called like this:

new Worker('longrunning.js')


I'm using the closure compiler to combine and minify all my JavaScript source code, and I'd rather not have to have my workers in separate files for distribution. Is there some way to do this?

new Worker(function() {
//Long-running work here
});


Given that first-class functions are so crucial to JavaScript, why does the standard way to do background work have to load a whole 'nother JavaScript file from the server?

Answer

http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers

What if you want to create your worker script on the fly, or create a self-contained page without having to create separate worker files? With Blob(), you can "inline" your worker in the same HTML file as your main logic by creating a URL handle to the worker code as a string


Full example of BLOB inline worker:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body>

  <div id="log"></div>

  <script id="worker1" type="javascript/worker">
    // This script won't be parsed by JS engines because its type is javascript/worker.
    self.onmessage = function(e) {
      self.postMessage('msg from worker');
    };
    // Rest of your worker code goes here.
  </script>

  <script>
    function log(msg) {
      // Use a fragment: browser will only render/reflow once.
      var fragment = document.createDocumentFragment();
      fragment.appendChild(document.createTextNode(msg));
      fragment.appendChild(document.createElement('br'));

      document.querySelector("#log").appendChild(fragment);
    }

    var blob = new Blob([
      document.querySelector('#worker1').textContent
    ], { type: "text/javascript" })

    // Note: window.webkitURL.createObjectURL() in Chrome 10+.
    var worker = new Worker(window.URL.createObjectURL(blob));
    worker.onmessage = function(e) {
      log("Received: " + e.data);
    }
    worker.postMessage("hello"); // Start the worker.
  </script>
</body>
</html>