Using web workers

  • Revision slug: Web/Guide/Performance/Using_web_workers
  • Revision title: Using web workers
  • Revision id: 407833
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment Moved From DOM/Using_web_workers to Web/Guide/Performance/Using_web_workers

Revision Content

Dedicated Web Workers provide a simple means for web content to run scripts in background threads. Once created, a worker can send messages to the spawning task by posting messages to an event handler specified by the creator, but working within another global context different from the current window (using the window shortcut instead of self in order to get the current global scope within a {{ domxref("Worker") }} will return, in fact, an error).

The worker thread can perform tasks without interfering with the user interface.  In addition, they can perform I/O using XMLHttpRequest (although the responseXML  and channel attributes are always null).

See {{ domxref("Worker") }} for reference documentation on workers; this article complements that one by offering examples and added details. For a list of functions available to workers, see Functions available to workers .

About thread safety

The Worker interface spawns real OS-level threads, and concurrency can cause interesting effects in your code if you aren't careful. However, in the case of web workers, the carefully controlled communication points with other threads means that it's actually very hard to cause concurrency problems.  There's no access to non-thread safe components or the DOM and you have to pass specific data in and out of a thread through serialized objects.  So you have to work really hard to cause problems in your code.

Spawning a worker

Creating a new worker is simple.  All you need to do is call the Worker()  constructor, specifying the URI of a script to execute in the worker thread, and, if you wish to be able to receive notifications from the worker, set the worker's onmessage property to an appropriate event handler function.

var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
  console.log("Called back by the worker!\n");
};

Alternatively, you could use addEventListener() :

var myWorker = new Worker("my_task.js");

myWorker.addEventListener("message", function (oEvent) {
  console.log("Called back by the worker!\n");
}, false);

myWorker.postMessage(""); // start the worker.

Line 1 in this example creates a new worker thread.  Line 3 sets up a listener to handle message events from the worker. This event handler will be called when the worker calls its own postMessage()  function. Finally, Line 7 starts the worker thread.

Note : The URI passed as parameter of the Worker constructor must obey the same-origin policy . There is currently disagreement among browsers vendors on what URIs are of the same-origin; Gecko 10.0 {{ geckoRelease("10.0") }} and later do allow data URIs and Internet Explorer 10 does not allow Blob URIs as a valid script for workers.

Passing data

Data passed between the main page and workers are copied, not shared. Objects are serialized as they're handed to the worker, and subsequently, de-serialized on the other end. The page and worker do not share the same instance, so the end result is that a duplicate is created on each end. Most browsers implement this feature as structured cloning.

Before continuing, let's create for didactical purpose a function named emulateMessage() which will simulate the behavior of a value which is cloned and not shared during the passage from a worker to the main page or vice versa:

function emulateMessage (vVal) {
    return eval("(" + JSON.stringify(vVal) + ")");
}

// Tests

// test #1
var example1 = new Number(3);
alert(typeof example1); // object
alert(typeof emulateMessage(example1)); // number

// test #2
var example2 = true;
alert(typeof example2); // boolean
alert(typeof emulateMessage(example2)); // boolean

// test #3
var example3 = new String("Hello World");
alert(typeof example3); // object
alert(typeof emulateMessage(example3)); // string

// test #4
var example4 = {
    "name": "John Smith",
    "age": 43
};
alert(typeof example4); // object
alert(typeof emulateMessage(example4)); // object

// test #5
function Animal (sType, nAge) {
    this.type = sType;
    this.age = nAge;
}
var example5 = new Animal("Cat", 3);
alert(example5.constructor); // Animal
alert(emulateMessage(example5).constructor); // Object

A value which is cloned and not shared is called message. Back to talk about workers, messages can be sent to and from the main thread by using postMessage(). The message event's data attribute contains data passed back from the worker.

example.html: (the main page):

var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
  console.log("Worker said : " + oEvent.data);
};

myWorker.postMessage("ali");

my_task.js (the worker):

postMessage("I\'m working before postMessage(\'ali\').");

onmessage = function (oEvent) {
  postMessage("Hi " + oEvent.data);
};
Note: As usual, background threads – including workers – cannot manipulate the DOM.  If actions taken by the background thread need to result in changes to the DOM, they should post messages back to their creators to do that work.

The structured cloning algorithm can accept JSON and a few things that JSON can't like circular references.

Passing data examples

Example #1: Create a generic "asynchronous eval()"

The following example shows how to use a worker in order to execute asynchronously any kind of JavaScript code through eval() within the worker:

// Syntax: asyncEval(code[, listener])

var asyncEval = (function () {

  var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");

  oParser.onmessage = function (oEvent) {
    if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
    delete aListeners[oEvent.data.id];
  };


  return function (sCode, fListener) {
    aListeners.push(fListener || null);
    oParser.postMessage({
      "id": aListeners.length - 1,
      "code": sCode
    });
  };

})();

Sample usage:

// asynchronous alert message...
asyncEval("3 + 2", function (sMessage) {
    alert("3 + 2 = " + sMessage);
});

// asynchronous print message...
asyncEval("\"Hello World!!!\"", function (sHTML) {
    document.body.appendChild(document.createTextNode(sHTML));
});

// asynchronous void...
asyncEval("(function () {\n\tvar oReq = new XMLHttpRequest();\n\toReq.open(\"get\", \"http://www.mozilla.org/\", false);\n\toReq.send(null);\n\treturn oReq.responseText;\n})()");

Example #2: Advanced passing JSON Data and creating a switching system

If you have to pass some complex data and have to call many different functions both in the main page and in the Worker, you can create a system like the following.

example.html (the main page):

<!doctype html>
<html>
<head>
<meta charset="UTF-8"  />
<title>MDN Example - Queryable worker</title>
<script type="text/javascript">
  /*
    QueryableWorker instances methods:
     * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
     * postMessage(string or JSON Data): see Worker.prototype.postMessage()
     * terminate(): terminates the Worker
     * addListener(name, function): adds a listener
     * removeListener(name): removes a listener
    QueryableWorker instances properties:
     * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
  */
  function QueryableWorker (sURL, fDefListener, fOnError) {
    var oInstance = this, oWorker = new Worker(sURL), oListeners = {};
    this.defaultListener = fDefListener || function () {};
    oWorker.onmessage = function (oEvent) {
      if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("vo42t30") && oEvent.data.hasOwnProperty("rnb93qh")) {
        oListeners[oEvent.data.vo42t30].apply(oInstance, oEvent.data.rnb93qh);
      } else {
        this.defaultListener.call(oInstance, oEvent.data);
      }
    };
    if (fOnError) { oWorker.onerror = fOnError; }
    this.sendQuery = function (/* queryable function name, argument to pass 1, argument to pass 2, etc. etc */) {
      if (arguments.length < 1) { throw new TypeError("QueryableWorker.sendQuery - not enough arguments"); return; }
      oWorker.postMessage({ "bk4e1h0": arguments[0], "ktp3fm1": Array.prototype.slice.call(arguments, 1) });
    };
    this.postMessage = function (vMsg) {
      //I just think there is no need to use call() method
      //how about just oWorker.postMessage(vMsg);
      //the same situation with terminate
      //well,just a little faster,no search up the prototye chain
      Worker.prototype.postMessage.call(oWorker, vMsg);
    };
    this.terminate = function () {
      Worker.prototype.terminate.call(oWorker);
    };
    this.addListener = function (sName, fListener) {
      oListeners[sName] = fListener;
    };
    this.removeListener = function (sName) {
      delete oListeners[sName];
    };
  };

  // your custom "queryable" worker
  var oMyTask = new QueryableWorker("my_task.js" /* , yourDefaultMessageListenerHere [optional], yourErrorListenerHere [optional] */);

  // your custom "listeners"

  oMyTask.addListener("printSomething", function (nResult) {
    document.getElementById("firstLink").parentNode.appendChild(document.createTextNode(" The difference is " + nResult + "!"));
  });

  oMyTask.addListener("alertSomething", function (nDeltaT, sUnit) {
    alert("Worker waited for " + nDeltaT + " " + sUnit + " :-)");
  });
</script>
</head>
<body>
  <ul>
    <li><a id="firstLink" href="javascript:oMyTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
    <li><a href="javascript:oMyTask.sendQuery('waitSomething');">Wait 3 seconds</a></li>
    <li><a href="javascript:oMyTask.terminate();">terminate() the Worker</a></li>
  </ul>
</body>
</html>

my_task.js (the worker):

// your custom PRIVATE functions

function myPrivateFunc1 () {
  // do something
}

function myPrivateFunc2 () {
  // do something
}

// etc. etc.

// your custom PUBLIC functions (i.e. queryable from the main page)

var queryableFunctions = {
  // example #1: get the difference between two numbers:
  getDifference: function (nMinuend, nSubtrahend) {
      reply("printSomething", nMinuend - nSubtrahend);
  },
  // example #2: wait three seconds
  waitSomething: function () {
      setTimeout(function() { reply("alertSomething", 3, "seconds"); }, 3000);
  }
};

// system functions

function defaultQuery (vMsg) {
  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
  // do something
}

function reply (/* listener name, argument to pass 1, argument to pass 2, etc. etc */) {
  if (arguments.length < 1) { throw new TypeError("reply - not enough arguments"); return; }
  postMessage({ "vo42t30": arguments[0], "rnb93qh": Array.prototype.slice.call(arguments, 1) });
}

onmessage = function (oEvent) {
  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("bk4e1h0") && oEvent.data.hasOwnProperty("ktp3fm1")) {
    queryableFunctions[oEvent.data.bk4e1h0].apply(self, oEvent.data.ktp3fm1);
  } else {
    defaultQuery(oEvent.data);
  }
};

It is a possible method to switch the content of each mainpage-worker – and vice versa – message.

Passing data by transferring ownership (transferable objects)

Google Chrome 17 and Firefox 18 contain an additional way to pass certain kind of objects (Transferable Objects) to/from a worker with high performance. Transferable objects are transferred from one context to another with a zero-copy operation. This means a vast performance improvement when sending large data. Think of it as pass-by-reference if you're from the C/C++ world. However, unlike pass-by-reference, the 'version' from the calling context is no longer available once transferred. Its ownership is transferred to the new context. For example, when transferring an ArrayBuffer from your main app to Worker, the original  ArrayBuffer  is cleared and no longer usable. Its content is (quite literally) transferred to the Worker context.

// Create a 32MB "file" and fill it.
var uInt8View = new Uint8Array(1024*1024*32); // 32MB
for (var i = 0; i < uInt8View.length; ++i) {
  uInt8View[i] = i;
}

worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);

For more information on transferable objects, see HTML5Rocks .

Spawning subworkers

Workers may spawn more workers if they wish.  So-called subworkers must be hosted within the same origin as the parent page.  Also, the URIs for subworkers are resolved relative to the parent worker's location rather than that of the owning page.  This makes it easier for workers to keep track of where their dependencies are.

Subworkers are currently not supported in Chrome. See crbug.com/31666 .

Embedded workers

There is not an "official" way to embed the code of a worker within a web page as for the {{ HTMLElement("script") }} elements. But a {{ HTMLElement("script") }} element which does not have a src attribute and has a type attribute that does not identify an executable mime-type will be considered a data block element, that JavaScript could use.  "Data blocks" is a more general feature of HTML5 that can carry almost any textual data. So, a worker could be embedded in this way:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>MDN Example - Embedded worker</title>
<script type="text/js-worker">
  // This script WON'T be parsed by JS engines because its mime-type is text/js-worker.
  var myVar = "Hello World!";
  // Rest of your worker code goes here.
</script>
<script type="text/javascript">
  // This script WILL be parsed by JS engines because its mime-type is text/javascript.
  function pageLog (sMsg) {
    // Use a fragment: browser will only render/reflow once.
    var oFragm = document.createDocumentFragment();
    oFragm.appendChild(document.createTextNode(sMsg));
    oFragm.appendChild(document.createElement("br"));
    document.querySelector("#logDisplay").appendChild(oFragm);
  }
</script>
<script type="text/js-worker">
  // This script WON'T be parsed by JS engines because its mime-type is text/js-worker.
  onmessage = function (oEvent) {
    postMessage(myVar);
  };
  // Rest of your worker code goes here.
</script>
<script type="text/javascript">
  // This script WILL be parsed by JS engines because its mime-type is text/javascript.

  // In the past...:
  // blob builder existed
  // ...but now we use Blob...:
  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"});

  // Creating a new document.worker property containing all our "text/js-worker" scripts.
  document.worker = new Worker(window.URL.createObjectURL(blob));

  document.worker.onmessage = function (oEvent) {
    pageLog("Received: " + oEvent.data);
  };

  // Start the worker.
  window.onload = function() { document.worker.postMessage(""); };
</script>
</head>
<body><div id="logDisplay"></div></body>
</html>

The embedded worker is now nested into a new custom document.worker property.

Timeouts and intervals

Workers can use timeouts and intervals just like the main thread can.  This can be useful, for example, if you want to have your worker thread run code periodically instead of nonstop.

See setTimeout() , clearTimeout() , setInterval() , and clearInterval() for details. See also: JavaScript Timers.

Terminating a worker

If you need to immediately terminate a running worker, you can do so by calling the worker's terminate() method:

myWorker.terminate();

The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.

Workers may close themselves by calling their own {{ ifmethod("nsIWorkerScope", "close") }} method:

self.close();

Handling errors

When a runtime error occurs in worker, its onerror event handler is called.  It receives an event named error which implements the ErrorEvent interface.  The event doesn't bubble and is cancelable; to prevent the default action from taking place, the worker can call the error event's preventDefault() method.

The error event has the following three fields that are of interest:

message
A human-readable error message.
filename
The name of the script file in which the error occurred.
lineno
The line number of the script file on which the error occurred.

Accessing the navigator object

Workers may access the navigator object, which is available within their scope.  It contains the following strings which can be used to identify the browser, just as can be done from normal scripts:

  • appName
  • appVersion
  • platform
  • userAgent

Importing scripts and libraries

Worker threads have access to a global function, importScripts() , which lets them import scripts or libraries into their scope.  It accepts as parameters zero or more URIs to resources to import; all of the following examples are valid:

importScripts();                        /* imports nothing */
importScripts('foo.js');                /* imports just "foo.js" */
importScripts('foo.js', 'bar.js');      /* imports two scripts */

The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can't be loaded, NETWORK_ERROR is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using {{ domxref("window.setTimeout()") }}) will still be functional though. Function declarations after the importScripts() method are also kept, since these are always evaluated before the rest of the code.

Note: Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into importScripts() .  This is done synchronously; importScripts() does not return until all the scripts have been loaded and executed.

Examples

This section provides several examples of how to use DOM workers.

Performing computations in the background

One way workers are useful is to allow your code to perform processor-intensive calculations without blocking the user interface thread.  In this example, a worker is used to calculate Fibonacci numbers.

The JavaScript code

The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the next section.

var results = [];

function resultReceiver(event) {
  results.push(parseInt(event.data));
  if (results.length == 2) {
    postMessage(results[0] + results[1]);
  }
}

function errorReceiver(event) {
  throw event.data;
}

onmessage = function(event) {
  var n = parseInt(event.data);

  if (n == 0 || n == 1) {
    postMessage(n);
    return;
  }

  for (var i = 1; i <= 2; i++) {
    var worker = new Worker("fibonacci.js");
    worker.onmessage = resultReceiver;
    worker.onerror = errorReceiver;
    worker.postMessage(n - i);
  }
 };

The worker sets the property onmessage  to a function which will receive messages sent when the worker object's  postMessage() is called.  (Note that this differs from defining a global variable of that name, or defining a function with that name.   var onmessage and function onmessage will define global properties with those names, but they will not register the function to receive messages sent by the  web page that created the worker.)  This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.

The HTML code

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"  />
    <title>Test threads fibonacci</title>
  </head>
  <body>

  <div id="result"></div>

  <script language="javascript">

    var worker = new Worker("fibonacci.js");

    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
      dump("Got: " + event.data + "\n");
    };

    worker.onerror = function(error) {
      dump("Worker error: " + error.message + "\n");
      throw error;
    };

    worker.postMessage("5");

  </script>
  </body>
</html>

The web page creates a div element with the ID  result , which gets used to display the result, then spawns the worker.  After spawning the worker, the onmessage handler is configured to display the results by setting the contents of the div element, and the onerror handler is set to dump the error message.

Finally, a message is sent to the worker to start it.

Try this example .

Performing web I/O in the background

You can find an example of this in the article Using workers in extensions .

Dividing tasks among multiple workers

As multi-core computers become increasingly common, it's often useful to divide computationally complex tasks among multiple workers, which may then perform those tasks on multiple-processor cores.

example coming soon

Creating workers from within workers

The Fibonacci example shown previously demonstrates that workers can in fact spawn additional workers.  This makes it easy to create recursive routines.

Browser compatibility

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Dedicated workers 3 3.5 (1.9.1) 10 10.60 4
Shared workers 5 --- --- 10.60 5
Passing data using structured cloning 13 8 10 11.50 5.1
Passing data using  transferable objects 17 {{ property_prefix("webkit") }} 18 --- --- ---
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Dedicated workers --- 0.16 3.5 (1.9.1) --- 11 5
Shared workers --- {{ CompatNo() }} --- --- --- ---
Passing data using structured cloning --- 0.16 8 --- --- ---
Passing data using  transferable objects ---   18 --- --- ---

See also

{{ HTML5ArticleTOC() }}

{{ languages ( {"es": "es/Usar_web_workers", "ja": "ja/Using_web_workers"} ) }}

Revision Source

<p>Dedicated Web Workers provide a simple means for web content to run scripts in background threads. Once created, a worker can send messages to the spawning task by posting messages to an event handler specified by the creator, but <strong>working within <a href="/en-US/docs/JavaScript/DedicatedWorkerGlobalScope" title="/en-US/docs/JavaScript/DedicatedWorkerGlobalScope">another global context</a> different from the current window</strong> (using the <a href="/en-US/docs/DOM/window" title="http://{{domxref(&quot;document.currentScript&quot;)}}"><code>window</code></a> shortcut instead of <a href="/en-US/docs/DOM/window.self" title="/en-US/docs/DOM/window.self"><code>self</code></a> in order to get the current global scope within a {{ domxref("Worker") }} will return, in fact, an error).</p>
<p>The worker thread can perform tasks without interfering with the user interface.&nbsp; In addition, they can perform I/O using <code><a class="internal" href="/en/nsIXMLHttpRequest" title="En/XMLHttpRequest">XMLHttpRequest</a></code> (although the <code>responseXML</code> &nbsp;and <code>channel</code> attributes are always null).</p>
<p>See {{ domxref("Worker") }} for reference documentation on workers; this article complements that one by offering examples and added details. For a list of functions available to workers, see <a href="/en/DOM/Worker/Functions_available_to_workers" title="En/DOM/Worker/Functions available to workers">Functions available to workers</a> .</p>
<h2 id="About_thread_safety">About thread safety</h2>
<p>The <code>Worker</code> interface spawns real OS-level threads, and concurrency can cause interesting effects in your code if you aren't careful. However, in the case of web workers, the carefully controlled communication points with other threads means that it's actually very hard to cause concurrency problems. &nbsp;There's no access to non-thread safe components or the DOM and you have to pass specific data in and out of a thread through serialized objects. &nbsp;So you have to work really hard to cause problems in your code.</p>
<h2 id="Spawning_a_worker">Spawning a worker</h2>
<p>Creating a new worker is simple.&nbsp; All you need to do is call the <code>Worker()</code> &nbsp;constructor, specifying the URI&nbsp;of a script to execute in the worker thread, and, if you wish to be able to receive notifications from the worker, set the worker's <code>onmessage</code> property to an appropriate event handler function.</p>
<div style="overflow:hidden">
  <pre class="brush: js">
var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
  console.log("Called back by the worker!\n");
};</pre>
</div>
<p>Alternatively, you could use <code>addEventListener()</code> :</p>
<div style="overflow:hidden">
  <pre class="brush: js">
var myWorker = new Worker("my_task.js");

myWorker.addEventListener("message", function (oEvent) {
  console.log("Called back by the worker!\n");
}, false);

myWorker.postMessage(""); // start the worker.</pre>
</div>
<p>Line 1 in this example creates a new worker thread.&nbsp; Line 3 sets up a listener to handle <code>message</code> events from the worker. This event handler will be called when the worker calls its own <code>postMessage()</code> &nbsp;function. Finally, Line 7 starts the worker thread.</p>
<div class="note">
  <strong>Note</strong> : The URI passed as parameter of the <code>Worker</code> constructor must obey the <a href="/en/Same_origin_policy_for_JavaScript" title="Same origin policy for JavaScript">same-origin policy</a> . There is currently disagreement among browsers vendors on what URIs are of the same-origin; Gecko 10.0 {{ geckoRelease("10.0") }} and later do allow data URIs and Internet Explorer 10 does not allow Blob URIs as a valid script for workers.</div>
<h2 id="Passing_data">Passing data</h2>
<p>Data passed between the main page and workers are <strong>copied</strong>, not shared. Objects are serialized as they're handed to the <code>worker</code>, and subsequently, de-serialized on the other end. The page and worker <strong>do not share the same instance</strong>, so the end result is that <strong>a duplicate</strong> is created on each end. Most browsers implement this feature as <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a>.</p>
<p>Before continuing, let's create for didactical purpose a function named <code>emulateMessage()</code> which will simulate the behavior of a value which is <em>cloned and not shared</em> during the passage from a <code>worker</code> to the main page or vice versa:</p>
<pre class="brush: js">
function emulateMessage (vVal) {
&nbsp;&nbsp; &nbsp;return eval("(" + JSON.stringify(vVal) + ")");
}

// Tests

// test #1
var example1 = new Number(3);
alert(typeof example1); // object
alert(typeof emulateMessage(example1)); // number

// test #2
var example2 = true;
alert(typeof example2); // boolean
alert(typeof emulateMessage(example2)); // boolean

// test #3
var example3 = new String("Hello World");
alert(typeof example3); // object
alert(typeof emulateMessage(example3)); // string

// test #4
var example4 = {
&nbsp;&nbsp;&nbsp; "name": "John Smith",
&nbsp;&nbsp;&nbsp; "age": 43
};
alert(typeof example4); // object
alert(typeof emulateMessage(example4)); // object

// test #5
function Animal (sType, nAge) {
&nbsp;&nbsp; &nbsp;this.type = sType;
&nbsp;&nbsp; &nbsp;this.age = nAge;
}
var example5 = new Animal("Cat", 3);
alert(example5.constructor); // Animal
alert(emulateMessage(example5).constructor); // Object</pre>
<p>A value which is cloned and not shared is called <em>message</em>. Back to talk about <code>workers</code>, <em>messages</em> can be sent to and from the main thread by using <code>postMessage()</code>. The <code>message</code> event's <code>data</code> attribute contains data passed back from the worker.</p>
<p><strong>example.html</strong>: (the main page):</p>
<pre class="brush: js">
var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
  console.log("Worker said : " + oEvent.data);
};

myWorker.postMessage("ali");</pre>
<p><strong>my_task.js</strong> (the worker):</p>
<pre class="brush: js">
postMessage("I\'m working before postMessage(\'ali\').");

onmessage = function (oEvent) {
  postMessage("Hi " + oEvent.data);
};</pre>
<div class="note">
  <strong>Note:</strong> As usual, background threads – including workers – <strong>cannot manipulate the DOM</strong>.&nbsp; If actions taken by the background thread need to result in changes to the DOM, they should post messages back to their creators to do that work.</div>
<p>The <a href="/en/DOM/The_structured_clone_algorithm" style="line-height: 1.572;" title="The structured clone algorithm">structured cloning</a>&nbsp;algorithm can accept JSON and a few things that JSON can't like circular references.</p>
<p><span style="font-family: Georgia, Times, 'Times New Roman', serif; font-size: 1.428em; line-height: 1.572;">Passing data examples</span></p>
<h4 id="Example_.231.3A_Create_a_generic_.22asynchronous_eval().22">Example #1: Create a generic "asynchronous <a href="/en-US/docs/JavaScript/Reference/Global_Objects/eval" title="/en-US/docs/JavaScript/Reference/Global_Objects/eval"><code>eval()</code></a>"</h4>
<p>The following example shows how to use a&nbsp;worker in order to execute <strong>asynchronously</strong> any kind of JavaScript code through <a href="/en-US/docs/JavaScript/Reference/Global_Objects/eval" title="/en-US/docs/JavaScript/Reference/Global_Objects/eval"><code>eval()</code></a> within the worker:</p>
<pre class="brush: js">
// Syntax: asyncEval(code[, listener])

var asyncEval = (function () {

&nbsp; var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");

&nbsp; oParser.onmessage = function (oEvent) {
&nbsp;&nbsp;&nbsp; if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
&nbsp;&nbsp;&nbsp; delete aListeners[oEvent.data.id];
&nbsp; };


&nbsp; return function (sCode, fListener) {
&nbsp;&nbsp;&nbsp; aListeners.push(fListener || null);
&nbsp;&nbsp;&nbsp; oParser.postMessage({
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "id": aListeners.length - 1,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "code": sCode
&nbsp;&nbsp;&nbsp; });
&nbsp; };

})();</pre>
<p>Sample usage:</p>
<pre class="brush: js">
// asynchronous alert message...
asyncEval("3 + 2", function (sMessage) {
&nbsp;&nbsp; &nbsp;alert("3 + 2 = " + sMessage);
});

// asynchronous print message...
asyncEval("\"Hello World!!!\"", function (sHTML) {
&nbsp;&nbsp; &nbsp;document.body.appendChild(document.createTextNode(sHTML));
});

// asynchronous void...
asyncEval("(function () {\n\tvar oReq = new XMLHttpRequest();\n\toReq.open(\"get\", \"http://www.mozilla.org/\", false);\n\toReq.send(null);\n\treturn oReq.responseText;\n})()");</pre>
<h4 id="Example_.232.3A_Advanced_passing_JSON_Data_and_creating_a_switching_system">Example #2: Advanced passing JSON Data and creating a switching system</h4>
<p>If you have to pass some complex data and have to call many different functions both in the main page and in the Worker, you can create a system like the following.</p>
<p><strong>example.html</strong> (the main page):</p>
<pre class="brush: html">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"  /&gt;
&lt;title&gt;MDN Example - Queryable worker&lt;/title&gt;
&lt;script type="text/javascript"&gt;
&nbsp; /*
&nbsp;&nbsp;&nbsp; QueryableWorker instances methods:
&nbsp;&nbsp; &nbsp; * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
&nbsp;&nbsp; &nbsp; * postMessage(string or JSON Data): see Worker.prototype.postMessage()
&nbsp;&nbsp; &nbsp; * terminate(): terminates the Worker
&nbsp;&nbsp; &nbsp; * addListener(name, function): adds a listener
&nbsp;&nbsp; &nbsp; * removeListener(name): removes a listener
&nbsp;&nbsp;&nbsp; QueryableWorker instances properties:
&nbsp;&nbsp; &nbsp; * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
&nbsp; */
&nbsp; function QueryableWorker (sURL, fDefListener, fOnError) {
&nbsp;&nbsp;&nbsp; var oInstance = this, oWorker = new Worker(sURL), oListeners = {};
&nbsp;&nbsp;&nbsp; this.defaultListener = fDefListener || function () {};
&nbsp;&nbsp;&nbsp; oWorker.onmessage = function (oEvent) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (oEvent.data instanceof Object &amp;&amp; oEvent.data.hasOwnProperty("vo42t30") &amp;&amp; oEvent.data.hasOwnProperty("rnb93qh")) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oListeners[oEvent.data.vo42t30].apply(oInstance, oEvent.data.rnb93qh);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.defaultListener.call(oInstance, oEvent.data);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; if (fOnError) { oWorker.onerror = fOnError; }
&nbsp;&nbsp;&nbsp; this.sendQuery = function (/* queryable function name, argument to pass 1, argument to pass 2, etc. etc */) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (arguments.length &lt; 1) { throw new TypeError("QueryableWorker.sendQuery - not enough arguments"); return; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oWorker.postMessage({ "bk4e1h0": arguments[0], "ktp3fm1": Array.prototype.slice.call(arguments, 1) });
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp; &nbsp;this.postMessage = function (vMsg) {
      //I just think there is no need to use call() method
      //how about just oWorker.postMessage(vMsg);
      //the same situation with terminate
      //well,just a little faster,no search up the prototye chain
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Worker.prototype.postMessage.call(oWorker, vMsg);
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; this.terminate = function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Worker.prototype.terminate.call(oWorker);
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; this.addListener = function (sName, fListener) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oListeners[sName] = fListener;
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; this.removeListener = function (sName) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete oListeners[sName];
&nbsp;&nbsp;&nbsp; };
&nbsp; };

&nbsp; // your custom "queryable" worker
&nbsp; var oMyTask = new QueryableWorker("my_task.js" /* , yourDefaultMessageListenerHere [optional], yourErrorListenerHere [optional] */);

&nbsp; // your custom "listeners"

&nbsp; oMyTask.addListener("printSomething", function (nResult) {
&nbsp;&nbsp;&nbsp; document.getElementById("firstLink").parentNode.appendChild(document.createTextNode(" The difference is " + nResult + "!"));
&nbsp; });

&nbsp; oMyTask.addListener("alertSomething", function (nDeltaT, sUnit) {
&nbsp;&nbsp;&nbsp; alert("Worker waited for " + nDeltaT + " " + sUnit + " :-)");
&nbsp; });
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&nbsp; &lt;ul&gt;
&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a id="firstLink" href="javascript:oMyTask.sendQuery('getDifference', 5, 3);"&gt;What is the difference between 5 and 3?&lt;/a&gt;&lt;/li&gt;
&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href="javascript:oMyTask.sendQuery('waitSomething');"&gt;Wait 3 seconds&lt;/a&gt;&lt;/li&gt;
&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href="javascript:oMyTask.terminate();"&gt;terminate() the Worker&lt;/a&gt;&lt;/li&gt;
&nbsp; &lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>my_task.js</strong> (the worker):</p>
<pre class="brush: js">
// your custom PRIVATE functions

function myPrivateFunc1 () {
&nbsp; // do something
}

function myPrivateFunc2 () {
&nbsp; // do something
}

// etc. etc.

// your custom PUBLIC functions (i.e. queryable from the main page)

var queryableFunctions = {
&nbsp; // example #1: get the difference between two numbers:
&nbsp; getDifference: function (nMinuend, nSubtrahend) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reply("printSomething", nMinuend - nSubtrahend);
&nbsp; },
&nbsp; // example #2: wait three seconds
&nbsp; waitSomething: function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(function() { reply("alertSomething", 3, "seconds"); }, 3000);
&nbsp; }
};

// system functions

function defaultQuery (vMsg) {
&nbsp; // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
&nbsp; // do something
}

function reply (/* listener name, argument to pass 1, argument to pass 2, etc. etc */) {
&nbsp; if (arguments.length &lt; 1) { throw new TypeError("reply - not enough arguments"); return; }
&nbsp; postMessage({ "vo42t30": arguments[0], "rnb93qh": Array.prototype.slice.call(arguments, 1) });
}

onmessage = function (oEvent) {
&nbsp; if (oEvent.data instanceof Object &amp;&amp; oEvent.data.hasOwnProperty("bk4e1h0") &amp;&amp; oEvent.data.hasOwnProperty("ktp3fm1")) {
&nbsp;&nbsp;&nbsp; queryableFunctions[oEvent.data.bk4e1h0].apply(self, oEvent.data.ktp3fm1);
&nbsp; } else {
&nbsp;&nbsp;&nbsp; defaultQuery(oEvent.data);
&nbsp; }
};</pre>
<p>It is a possible method to switch the content of each mainpage-worker – and vice versa – message.</p>
<h3 id="Passing_data_by_transferring_ownership_(transferable_objects)">Passing data by transferring ownership (transferable objects)</h3>
<p>Google Chrome 17 and Firefox 18 contain an additional way to pass certain kind of objects (<a class="external" href="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">Transferable Objects</a>) to/from a worker with high performance. Transferable objects are transferred from one context to another with a zero-copy operation. This means a vast performance improvement when sending large data. Think of it as pass-by-reference if you're from the C/C++ world. However, unlike pass-by-reference, the 'version' from the calling context is no longer available once transferred. Its ownership is transferred to the new context. For example, when transferring an<font face="'Courier New', 'Andale Mono', monospace"> <span style="line-height: normal;"><a href="/en/JavaScript_typed_arrays/ArrayBuffer" title="ArrayBuffer">ArrayBuffer </a></span></font>from your main app to Worker, the original&nbsp; <code>ArrayBuffer</code> &nbsp;is cleared and no longer usable. Its content is (quite literally) transferred to the Worker context.</p>
<pre class="brush: js">
// Create a 32MB "file" and fill it.
var uInt8View = new Uint8Array(1024*1024*32); // 32MB
for (var i = 0; i &lt; uInt8View.length; ++i) {
  uInt8View[i] = i;
}

worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
</pre>
<p>For more information on transferable objects, <a class="external" href="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast" title="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast">see HTML5Rocks</a> .</p>
<h2 id="Spawning_subworkers">Spawning subworkers</h2>
<p>Workers may spawn more workers if they wish.&nbsp; So-called subworkers must be hosted within the same origin as the parent page.&nbsp; Also, the URIs for subworkers are resolved relative to the parent worker's location rather than that of the owning page.&nbsp; This makes it easier for workers to keep track of where their dependencies are.</p>
<p>Subworkers are currently not supported in Chrome. See <a class="external" href="http://code.google.com/p/chromium/issues/detail?id=31666" title="http://code.google.com/p/chromium/issues/detail?id=31666">crbug.com/31666</a> .</p>
<h2 id="Embedded_workers">Embedded workers</h2>
<p>There is not an "official" way to embed the code of a worker within a web page as for the {{ HTMLElement("script") }} elements. But a {{ HTMLElement("script") }} element which does not have a <code>src</code> attribute and has a <code>type</code> attribute that does not identify an executable mime-type will be considered a data block element, that JavaScript could use.&nbsp; "Data blocks" is a more general feature of HTML5 that can carry almost any textual data. So, a worker could be embedded in this way:</p>
<pre class="brush: html">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8" /&gt;
&lt;title&gt;MDN Example - Embedded worker&lt;/title&gt;
&lt;script type="text/js-worker"&gt;
&nbsp; // This script WON'T be parsed by JS engines because its mime-type is text/js-worker.
&nbsp; var myVar = "Hello World!";
&nbsp; // Rest of your worker code goes here.
&lt;/script&gt;
&lt;script type="text/javascript"&gt;
&nbsp; // This script WILL be parsed by JS engines because its mime-type is text/javascript.
&nbsp; function pageLog (sMsg) {
&nbsp;&nbsp;&nbsp; // Use a fragment: browser will only render/reflow once.
&nbsp;&nbsp;&nbsp; var oFragm = document.createDocumentFragment();
&nbsp;&nbsp;&nbsp; oFragm.appendChild(document.createTextNode(sMsg));
&nbsp;&nbsp;&nbsp; oFragm.appendChild(document.createElement("br"));
&nbsp;&nbsp;&nbsp; document.querySelector("#logDisplay").appendChild(oFragm);
&nbsp; }
&lt;/script&gt;
&lt;script type="text/js-worker"&gt;
&nbsp; // This script WON'T be parsed by JS engines because its mime-type is text/js-worker.
&nbsp; onmessage = function (oEvent) {
&nbsp;&nbsp;&nbsp; postMessage(myVar);
&nbsp; };
&nbsp; // Rest of your worker code goes here.
&lt;/script&gt;
&lt;script type="text/javascript"&gt;
&nbsp; // This script WILL be parsed by JS engines because its mime-type is text/javascript.

&nbsp; // In the past...:
&nbsp; // blob builder existed
&nbsp; // ...but now we use Blob...:
&nbsp; var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"});

&nbsp; // Creating a new document.worker property containing all our "text/js-worker" scripts.
&nbsp; document.worker = new Worker(window.URL.createObjectURL(blob));

&nbsp; document.worker.onmessage = function (oEvent) {
&nbsp;&nbsp;&nbsp; pageLog("Received: " + oEvent.data);
&nbsp; };

&nbsp; // Start the worker.
&nbsp; window.onload = function() { document.worker.postMessage(""); };
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;&lt;div id="logDisplay"&gt;&lt;/div&gt;&lt;/body&gt;
&lt;/html&gt;</pre>
<p>The embedded worker is now nested into a new custom <code>document.worker</code> property.</p>
<h2 id="Timeouts_and_intervals">Timeouts and intervals</h2>
<p>Workers can use timeouts and intervals just like the main thread can.&nbsp; This can be useful, for example, if you want to have your worker thread run code periodically instead of nonstop.</p>
<p>See <a class="internal" href="/en/DOM/window.setTimeout" title="En/DOM/Window.setTimeout"> <code>setTimeout()</code> </a> , <a class="internal" href="/en/DOM/window.clearTimeout" title="En/DOM/Window.clearTimeout"> <code>clearTimeout()</code> </a> , <a class="internal" href="/en/DOM/window.setInterval" title="En/DOM/Window.setInterval"> <code>setInterval()</code> </a> , and <a class="internal" href="/en/DOM/window.clearInterval" title="En/DOM/Window.clearInterval"> <code>clearInterval()</code> </a> for details. See also: <a href="/en-US/docs/JavaScript/Timers" title="/en-US/docs/JavaScript/Timers">JavaScript Timers</a>.</p>
<h2 id="Terminating_a_worker">Terminating a worker</h2>
<p>If you need to immediately terminate a running worker, you can do so by calling the worker's <code>terminate()</code> method:</p>
<pre class="syntaxbox">
myWorker.terminate();</pre>
<p>The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.</p>
<p>Workers may close themselves by calling their own {{ ifmethod("nsIWorkerScope", "close") }} method:</p>
<pre class="syntaxbox">
self.close();</pre>
<h2 id="Handling_errors">Handling errors</h2>
<p>When a runtime error occurs in worker, its <code>onerror</code> event handler is called.&nbsp; It receives an event named <code>error</code> which implements the <code>ErrorEvent</code> interface.&nbsp; The event doesn't bubble and is cancelable; to prevent the default action from taking place, the worker can call the error event's <a class="internal" href="/en/DOM/event.preventDefault" title="En/DOM/Event.preventDefault"> <code>preventDefault()</code> </a> method.</p>
<p>The error event has the following three fields that are of interest:</p>
<dl>
  <dt>
    <code>message</code></dt>
  <dd>
    A human-readable error message.</dd>
  <dt>
    <code>filename</code></dt>
  <dd>
    The name of the script file in which the error occurred.</dd>
  <dt>
    <code>lineno</code></dt>
  <dd>
    The line number of the script file on which the error occurred.</dd>
</dl>
<h2 id="Accessing_the_navigator_object">Accessing the navigator object</h2>
<p>Workers may access the <code>navigator</code> object, which is available within their scope.&nbsp; It contains the following strings which can be used to identify the browser, just as can be done from normal scripts:</p>
<ul>
  <li><code>appName</code></li>
  <li><code>appVersion</code></li>
  <li><code>platform</code></li>
  <li><code>userAgent</code></li>
</ul>
<h2 id="Importing_scripts_and_libraries">Importing scripts and libraries</h2>
<p>Worker threads have access to a global function, <code>importScripts()</code> , which lets them import scripts or libraries into their scope.&nbsp; It accepts as parameters zero or more URIs to resources to import; all of the following examples are valid:</p>
<pre class="brush: js">
importScripts();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* imports nothing */
importScripts('foo.js');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*&nbsp;imports just "foo.js" */
importScripts('foo.js', 'bar.js');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* imports two scripts */
</pre>
<p>The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can't be loaded, <code>NETWORK_ERROR</code> is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using {{ domxref("window.setTimeout()") }}) will still be functional though. Function declarations <strong>after</strong> the <code>importScripts()</code> method are also kept, since these are always evaluated before the rest of the code.</p>
<div class="note">
  <strong>Note:</strong> Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into <code>importScripts()</code> .&nbsp; This is done synchronously; <code>importScripts()</code> does not return until all the scripts have been loaded and executed.</div>
<h2 id="Examples">Examples</h2>
<p>This section provides several examples of how to use DOM workers.</p>
<h3 id="Performing_computations_in_the_background">Performing computations in the background</h3>
<p>One way workers are useful is to allow your code to perform processor-intensive calculations without blocking the user interface thread.&nbsp; In this example, a worker is used to calculate Fibonacci numbers.</p>
<h4 id="The_JavaScript_code">The JavaScript code</h4>
<p>The following JavaScript code is stored in the "fibonacci.js"&nbsp;file referenced by the HTML&nbsp;in the next section.</p>
<pre class="brush: js">
var results = [];

function resultReceiver(event) {
  results.push(parseInt(event.data));
  if (results.length == 2) {
    postMessage(results[0] + results[1]);
  }
}

function errorReceiver(event) {
  throw event.data;
}

onmessage = function(event) {
  var n = parseInt(event.data);

  if (n == 0 || n == 1) {
    postMessage(n);
    return;
  }

  for (var i = 1; i &lt;= 2; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;var worker = new Worker("fibonacci.js");
&nbsp;&nbsp;&nbsp;&nbsp;worker.onmessage = resultReceiver;
&nbsp;&nbsp;&nbsp;&nbsp;worker.onerror = errorReceiver;
&nbsp;&nbsp;&nbsp;&nbsp;worker.postMessage(n - i);
&nbsp;&nbsp;}
 };</pre>
<p>The worker sets the property <code>onmessage</code> &nbsp;to a function which will receive messages sent when&nbsp;the worker object's&nbsp; <code>postMessage()</code> is called. &nbsp;(Note that this differs from defining a global <em>variable</em> of that name, or defining a <em>function</em> with that name. &nbsp; <code>var onmessage</code> and <code>function onmessage</code> will define global properties with those names, but they will not register the function to receive messages sent by the &nbsp;web page that created the worker.) &nbsp;This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.</p>
<h4 id="The_HTML.C2.A0code">The HTML&nbsp;code</h4>
<pre class="brush: html">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8"  /&gt;
    &lt;title&gt;Test threads fibonacci&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;

  &lt;div id="result"&gt;&lt;/div&gt;

  &lt;script language="javascript"&gt;

    var worker = new Worker("fibonacci.js");

    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
      dump("Got: " + event.data + "\n");
    };

    worker.onerror = function(error) {
      dump("Worker error: " + error.message + "\n");
      throw error;
    };

    worker.postMessage("5");

  &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The web page creates a <code>div</code> element with the ID&nbsp; <code>result</code> , which gets used to display the result, then spawns the worker.&nbsp; After spawning the worker, the <code>onmessage</code> handler is configured to display the results by setting the contents of the <code>div</code> element, and the <code>onerror</code> handler is set to <a class="external" href="/en/Debugging_JavaScript#dump()" title="https://developer.mozilla.org/editor/fckeditor/core/editor/en/Debugging_JavaScript#dump()">dump</a> the error message.</p>
<p>Finally, a message is sent to the worker to start it.</p>
<p><a class="external" href="/samples/workers/fibonacci" title="https://developer.mozilla.org/samples/workers/fibonacci/">Try this example</a> .</p>
<h3 id="Performing_web_I.2FO_in_the_background">Performing web I/O in the background</h3>
<p>You can find an example of this in the article <a class="internal" href="/En/Using_workers_in_extensions" title="En/Using workers in extensions">Using workers in extensions</a> .</p>
<h3 id="Dividing_tasks_among_multiple_workers">Dividing tasks among multiple workers</h3>
<p>As multi-core computers become increasingly common, it's often useful to divide computationally complex tasks among multiple workers, which may then perform those tasks on multiple-processor cores.</p>
<p>example coming soon</p>
<h3 id="Creating_workers_from_within_workers">Creating workers from within workers</h3>
<p>The Fibonacci example shown previously demonstrates that workers can in fact <a href="#Spawning_subworkers">spawn additional workers</a>.&nbsp; This makes it easy to create recursive routines.</p>
<h2 id="Browser_Compatibility" name="Browser_Compatibility">Browser compatibility</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Chrome</th>
        <th>Firefox (Gecko)</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari (WebKit)</th>
      </tr>
      <tr>
        <td>Dedicated workers</td>
        <td>3</td>
        <td>3.5 (1.9.1)</td>
        <td>10</td>
        <td>10.60</td>
        <td>4</td>
      </tr>
      <tr>
        <td>Shared workers</td>
        <td>5</td>
        <td>---</td>
        <td>---</td>
        <td>10.60</td>
        <td>5</td>
      </tr>
      <tr>
        <td>Passing data using <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a> .&nbsp;</td>
        <td>13</td>
        <td>8</td>
        <td>10</td>
        <td>11.50</td>
        <td>5.1</td>
      </tr>
      <tr>
        <td>Passing data using&nbsp; <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objects" title="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">transferable objects</a></td>
        <td>17 {{ property_prefix("webkit") }}</td>
        <td>18</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Android</th>
        <th>Chrome for Android</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>IE&nbsp;Phone</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Dedicated workers</td>
        <td>---</td>
        <td>0.16</td>
        <td>3.5 (1.9.1)</td>
        <td>---</td>
        <td>11</td>
        <td>5</td>
      </tr>
      <tr>
        <td>Shared workers</td>
        <td>---</td>
        <td>{{ CompatNo() }}</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
      <tr>
        <td>Passing data using <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a> .&nbsp;</td>
        <td>---</td>
        <td>0.16</td>
        <td>8</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
      <tr>
        <td>Passing data using&nbsp; <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objectshtml#transferable-objects" title="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">transferable objects</a></td>
        <td>---</td>
        <td>&nbsp;</td>
        <td>18</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="See_also">See also</h2>
<ul>
  <li>{{ spec("http://dev.w3.org/html5/workers/", "File API Specification: Web Workers", "ED") }}</li>
  <li><code><a class="internal" href="/en/DOM/Worker" title="En/DOM/Worker">Worker</a></code> interface</li>
  <li><code><a class="internal" href="/en/DOM/SharedWorker" title="En/DOM/SharedWorker">SharedWorker</a></code> interface</li>
  <li><a href="/en/DOM/Worker/Functions_available_to_workers" title="En/DOM/Worker/Functions available to workers">Functions available to workers</a></li>
  <li><a class="external" href="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers" title="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers">HTML5Rocks - The Basics of Web Workers</a></li>
  <li><code><a class="external" href="http://code.google.com/p/chromium/issues/detail?id=127990" title="Chrome has Problems with many workers">Chrome has problems when using too many workers</a></code></li>
</ul>
<p>{{ HTML5ArticleTOC() }}</p>
<p>{{ languages ( {"es": "es/Usar_web_workers", "ja": "ja/Using_web_workers"} ) }}</p>
Revert to this revision