252 Chapter 10—Web Workers
Clicking the Start button executes the startCalc() function. This reads the step
value set in the option field and then initializes the web worker worker with the
script date_worker.js:
var opts = document.forms.stepForm.step.options;
startCalc = function() {
var step = opts[opts.selectedIndex].value;
var w = new Worker('date_worker.js');
w.postMessage(step);
The call of the postMessage() function to which the selected step size is passed
communicates with the event listener for the message event in the script date_
worker.js. Now the worker starts working:
addEventListener('message', function(evt) {
var today = new Date();
var oldMonth = -1;
for (var i=0; i<today; i+=Number(evt.data)*1000) {
var d = new Date(i);
if (d.getDate() == 29 && d.getMonth() == 1
&& d.getHours() == 12 && d.getMinutes() == 0) {
postMessage(d.toLocaleString());
}
if (d.getMonth() != oldMonth) {
postMessage("y "+d.getFullYear()+"-"
+(d.getMonth()+1));
oldMonth = d.getMonth();
}
}
}, false);
A for loop in the worker runs from the second 0 to the current date (today), con-
verting the value passed by postMessage() to a number via the Number() function
and then multiplying it by 1000 to get the step size. Access to the postMessage()
data takes place via the data attribute, which you have already encountered in the
previous chapter about WebSockets. Multiplying by 1000 is necessary because
the variable today contains the current value in milliseconds, not in seconds. If a
date in the loop is recognized as February 29, the worker sends a message to the
calling script and passes the day as a formatted string.
To indicate the current progress of the calculation, the program sends another
message as soon as the loop reaches a new month. This message starts with the
string "y " and also contains the year and the month. The following listing shows
how the calling script distinguishes this message from a leap year notification:
w.onmessage = function(evt) {
if (evt.data.substr(0,2) == "y ") {