Doing two things at once – multithreading

Doing two things at once is hard. For many years the solution in the computer world was to use either multiple processes or multiple threads. The difference between the two is fuzzy due to implementation differences on different operating systems but threads are typically lighter-weight versions of processes. JavaScript on the browser supports neither of these approaches.

Historically, there has been no real need for multithreading on a browser. JavaScript was used to manipulate the user interface. When manipulating a UI, even in other languages and windowing environments, only one thread is permitted to act at a time. This avoids race conditions that would be very obvious to users.

However, as JavaScript grows in popularity, more and more complicated software is being written to run inside the browser. Sometimes that software could really benefit from performing complex calculations in the background.

Web workers provide a mechanism for doing two things at once in a browser. Although a fairly recent innovation, web workers now have good support in mainstream browsers. In effect a worker is a background thread that can communicate with the main thread using messages. Web workers must be self-contained in a single JavaScript file.

To make use of web workers is fairly easy. We'll revisit our example from a few chapters ago when we looked at the fibonacci sequence. The worker process listens for messages like so:

self.addEventListener('message', function(e) {
  var data = e.data;
  if(data.cmd == 'startCalculation'){
    self.postMessage({event: 'calculationStarted'});
    var result = fib(data.parameters.number);
    self.postMessage({event: 'calculationComplete', result: result});
  };
}, false);

Here we start a new instance of fib any time we get a startCalculation message. fib is simply the naive implementation from earlier.

The main thread loads the worker process from its external file and attaches a number of listeners:

function startThread(){
  worker =  new Worker("worker.js");
  worker.addEventListener('message', function(message) {
    logEvent(message.data.event);
    if(message.data.event == "calculationComplete"){
      writeResult(message.data.result);
    }
    if(message.data.event == "calculationStarted"){
      document.getElementById("result").innerHTML = "working";
    }
  });
};

In order to start the calculation, all that is needed is to send a command:

worker.postMessage({cmd: 'startCalculation', parameters: { number: 40}});

Here we pass the number of the term in the sequence we want to calculate. While the calculation is running in the background the main thread is free to do whatever it likes. When the message is received back from the worker it is placed in the normal event loop to be processed:

Doing two things at once – multithreading

Web workers may be useful to you if you have to do any time consuming calculations in JavaScript.

If you're making use of server-side JavaScript through the use of Node.js then there is a different approach to doing more than one thing at a time. Node.js offers the ability to fork child processes and provides an interface not dissimilar to the web worker one to communicate between the child and parent processes. This method forks an entire process though, which is much more resource intensive than using lightweight threads.

Some other tools exist that create lighter-weight background workers in Node.js. These are probably a closer parallel to what exists on the web side than forking a child process.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset