9

I'm trying to understand this example:

HTML (main code):

   <html>  
     <title>Test threads fibonacci</title>  
     <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> 

Javascript (worker code):

   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);  
     }  
  };  

I have the following questions:

  • When exactly the worker code starts to run ? Immediately after the execution of var worker = new Worker("fibonacci.js"); ?

  • Is that true that onmessage = function(event) { ... } assignment in the worker code will be executed before worker.postMessage("5"); in the main code ?

  • Can worker code access global variables that are defined in the main code (like worker)?

  • Can main code access global variables that are defined in the worker code (like results)?

  • It seems to me that worker.onmessage = function(event) {...} in the main code has the same meaning like onmessage = function(event) {...} in the worker code (which is onmessage event handler of the worker). Where am I wrong ? What is the difference between them ?

  • What this code should actually do ? When I run it here it just prints "5". Is that what it is supposed to do, or I'm missing something ?

Thanks a lot !

Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746
  • If you haven't already, give the spec (http://www.w3.org/TR/workers/) a read through. It *should* cover most or all of that. – T.J. Crowder May 24 '10 at 11:12
  • I have to say that a Fibonacci calculator is not high on the list of things I'd've picked to build an example of web workers around! :-) Not if I wanted to do something that would be a simple and clear example. This may be useful: http://ejohn.org/blog/web-workers/ BTW, I also get `5` when I run that example in Firefox; I suspect it may have been written to an early version of web workers and/or `postMessage` and that Firefox 3.6 (now) supports a later iteration. (This is very cutting edge stuff.) – T.J. Crowder May 24 '10 at 11:22
  • I want to learn this stuff from examples, and I saw some examples before wrote this. I still have basic misunderstandings in how this works. I would be glad if anyone could answer to my questions. Reading the Spec is too painful for me right now. – Misha Moroshko May 24 '10 at 11:39
  • TJ do you understand why it is that the Worker in the main page (the one in the first chunk of code above) gets the messages posted by the Fib workers? I mean, what makes it different? – Pointy May 24 '10 at 12:45

2 Answers2

9

Check out HTML5 Rocks: The Basics of Web Workers for general tutorial.

  • Workers will start as soon as you call the postMessage method of the worker.
  • the function bound to worker's onmessage in the main code will work when the worker calls postMessage.
  • global variables are not shared between main and worker threads. The only way to pass data is through messaging via postMessage.
  • as you suspected, the onmessage on both worker and main code has the same meaning. It is an event handler for when the thread receives a message event. You can even use addEventListener instead, catching message event:

Main Code:

function showResult(event) {  
   document.getElementById("result").textContent = event.data;  
   dump("Got: " + event.data + "\n");  
}
var worker = new Worker("fibonacci.js");
worker.addEventListener('message', showResult, false);

Worker code:

addEventListener('message', resultReceiver, false);

The fibonacci example you took is a recursive worker example. If not using workers, it would be something like this:

function fibonacci(n) {
    if (n == 0 || n == 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

var result = fibonacci(5);
dump("Got: " + result + "\n");

(oh no, I'm not going to do a stackless for you. You write it yourself!)

syockit
  • 5,747
  • 1
  • 24
  • 33
1

I also want to add that you can debug web workers only in Chromium based browsers. You have to select Sources in developer panel and in right column expand bottom line Workers and then choose check box pause on start.

r90t
  • 366
  • 3
  • 15