Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

Using Web Workers and keeping support for IE9

0.00/5 (No votes)
2 Apr 2012CPOL1 min read 19.1K  
Here's a simple tip to use web worker code; yet maintain support for IE9.

Introduction

Included in the HTML5 specification is a background worker type called a Web Worker. Even if you are developing an HTML5 based site, you still cannot fully use this because of IE9 which does not have support. On the mobile browser front, you'll need the latest iOS or Opera at the moment. See http://www.caniuse.com/#feat=webworkers for updated information.

Background

The concepts and implementations for Web Workers were already documented in two very good articles:

This is not a tutorial on how to use them; it's a simple example of how to use them and not have to worry about browser support.

Using the code

A common method of this might be to check for worker support, and have two different code paths to run your task. Your task may be an HTTP request, image processing, or any kind of processor/network intensive method. In any case, I prefer to have only one code path when possible. This helps in debugging, and when changes are needed.

With that in mind, here's our simple HTML file. It calls a specific JavaScript function either in a worker (if possible) or without if not possible.

HTML
<!DOCTYPE html>
<html>
<head>
   <title>Worker test</title>
   <script src="worker.js"></script>
   <script>

      // Constructor for our object the worker will process.
      function Foo(i) {
         this.iLoopTo = i;
      }
      window.onload = function () {
         // counting to a billion to slow us up
         var f = new Foo(1000000000);
         // If the bowser handles workers, use it.
         if (window["Worker"]) {
            
            // Create a worker, and assign the callback
            var w = new Worker("worker.js");
            w.onmessage = workerCallback;
            w.postMessage(f);
         }
         else {
            // Calling this in our own thread, NOT in a worker            
            countToNum(f);
         }
      }
      function workerCallback(event) {
         // If there's a data property, we came from a worker.
         if (event.data) {
            event = event.data;
         }
         document.getElementById("p1").innerHTML = event;
      };
   </script>
</head>
<body>
   <p id="p1">Waiting for something to process...</p>
</body>
</html>

And, here's the corresponding worker.js file:

JavaScript
onmessage = countToNum;
function countToNum(event) {
   var obj = event;
   var isWorker = false;
   // If we have a data property, assume this is a real worker   
   if (obj.data) {
      obj = obj.data;
      isWorker = true;
   }
   // Here's some code just to slow us down.
   // Typically this could be a data load or other task.
   var f = 0;
   for (var i = 0; i < obj.iLoopTo; i++) {
      f += 1;
   }
   // And post back to the DOM thread
   if (isWorker) {
      postMessage("Counted to " + f + " in a worker");
   }
   else {
      workerCallback("Counted to " + f + " not in a worker");
   }
}

Points of Interest

You'll notice that in IE9 the text on the page of "Waiting for something to process" never shows. The script takes off and IE becomes unresponsive for a few seconds while that happens. Then the final output shows up instead. There will be minor nuances like this. Also, the browser warning that a script is taking a long time would still occur here; but there's no way around that until your users update their browsers.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)