Question about the web worker event raising

Apr 12, 2013 at 3:29 PM
Hi Jeremy,
I am currently following the last presentation and trying to figure out the web worker functionality.
If I look at the following code:

//first we create a web worker and define the js file that defines it
        var worker = new Worker("/demos/webworker/task.js");

        //this is how the web worker talks to us (the main thread)
        worker.onmessage = function(e) {
            log("The worker said " + e.data);
        };

        //and this is how we talk to the web worker
        worker.postMessage("Hey there, worker.");
How can be guaranteed that after executing the last line, first the task.js onMessage will trigger and after that the worker.onmessage triggers?
Is there any ordering constraint being done in both threads?
Coordinator
Apr 12, 2013 at 3:31 PM
Edited Apr 12, 2013 at 3:49 PM
There are no order constraints. I’ve been meaning to experiment with passing WinJS promises instead of primitive types or objects to see if that would allow awaiting a result. I’ll see if I can find time to test that.
Coordinator
Apr 12, 2013 at 3:52 PM
I did some testing and it is not possible to pass promises between the threads because there is not shared memory between them. You will get a DataCloneError if you attempt it. There is a good discussion on SO about it here.
Since there is an event model with a web worker, an asynchronous pattern is not really necessary anyway. Just do whatever you want in your web worker and raise an event (self.postMessage()) whenever you'd like.
Hope that helps.
Apr 12, 2013 at 4:26 PM
Hi Jeremy,

First of all, great presentations about HTML5 and CSS3 and thanks for the detailed response.
I just read the following line:
worker.onmessage = function(e)..... as overwriting the onmessage event handler of the worker.
Like when specifying button.onclick = sayHi(), which will overwrite any previous onclick event the button had defined.
So I'm reading this as: The onmessage in the task.js will be overwritten by the statement "worker.onmessage = function(e)...".
I have looked on W3C and it is explained to use worker.onmessage =... to listen to a worker, but again the assignment statement does not make it intuitive.
I hope my confusion can be understood or maybe I may have overlooked something?
Coordinator
Apr 12, 2013 at 4:33 PM
Edited Apr 12, 2013 at 4:36 PM
I'm not sure I totally understand your latest question, but I'll attempt to answer. Let me know if I miss entirely.
There are two ways to wire a function to an event.
The first is to set the event property (i.e. onclick, onmessage, onmouseover, etc.).
The second is to use addEventListener.
I'll focus on the first. I tend to prefer it unless I need to wire multiple functions to a single event.
The onmessage property of the worker is expecting a value that is a function object. You can give it anything that evaluates to a function object. It can be a declared, named function or it can be an anonymous function. Here are some examples:
//Example 1 - declared named function
//notice that the myFunction is specified without parenthesis because we're not executing the function but simply setting it
worker.onmessage = myFunction;

function myFunction() {
  //do something
}

//Example 2 - anonymous function
worker.onmessage = function() {
  //do something
}
The second example is the shortest and I tend to use that pattern.
Let me know if that's still not clear.
Apr 12, 2013 at 4:45 PM
Hi Jeremy,

Thanks for your explanation.
What I mean to say is that you overwrite the onmessage event of the worker in the file task,js, by saying "worker.onmessage = myFunction;"

The original definition of the event in task.js:

self.onmessage = function (e) {
//here's how we talk to the main thread
self.postMessage("\"Hey, boss. I heard you say '" + e.data + "\"");
};

To my perception you are overwriting everything that is stated after the "self.onmessage =" with myFunction.

If this is true, then the ordering is important, because if you overwrite it before getting the answer back from the worker, it will not give the "Hey, boss..." string back, but rather "The worker said Hey there worker".

I hope my explanation is clear. I wouldn't want to generate more confusion (as I am already pretty confused :p)
Coordinator
Apr 12, 2013 at 4:50 PM
Aha. I believe I understand now.
No, those are two different things. The worker.onmessage is what the worker should do when the master sends a message (using worker.postMessage("..."). The self.postMessage is how the worker tells the master something. It will not override the worker.postMessage.
Apr 12, 2013 at 4:58 PM
Hi Jeremy,

Yes, that's exactly it!
To add it into a final statement (just to confirm):
  1. The worker's self.postMessage sends a message to the master and triggers the master's worker.onmessage.
  2. The master's worker.postMessage sends a message to the worker and triggers the worker's self.onmessage.
Thanks again for your time and your patience!
Coordinator
Apr 12, 2013 at 5:00 PM
Edited Apr 17, 2013 at 11:42 AM
Exactly.