Webworkers

File: webworkers.html

<!DOCTYPE html>
<html>
<head>
  <title>math.js | web workers</title>
</head>
<body>

<p>
  In this example, a math.js parser is running in a separate
  <a href="http://www.html5rocks.com/en/tutorials/workers/basics/">web worker</a>,
  preventing the user interface from freezing during heavy calculations.
</p>

<p id="results"></p>

<script>
  /**
   * MathWorker evaluates expressions asynchronously in a web worker.
   *
   * Example usage:
   *
   *     var worker = new MathWorker();
   *     var expr = '12 / (2.3 + 0.7)';
   *     worker.eval(expr, function (err, result) {
   *       console.log(err, result)
   *     });
   */
  function MathWorker () {
    this.worker = new Worker('worker.js');
    this.callbacks = {};
    this.seq = 0;

    // create a listener to receive responses from the web worker
    var me = this;
    this.worker.addEventListener('message', function(event) {
      var response = JSON.parse(event.data);

      // find the callback corresponding to this response
      var callback = me.callbacks[response.id];
      delete me.callbacks[response.id];

      // call the requests callback with the result
      callback(response.err, response.result);
    }, false);
  }

  /**
   * Evaluate an expression
   * @param {string} expr
   * @param {Function} callback   Called as callback(err, result)
   */
  MathWorker.prototype.eval = function eval (expr, callback) {
    // build a request,
    // add an id so we can link returned responses to the right callback
    var id = this.seq++;
    var request = {
      id: id,
      expr: expr
    };

    // queue the callback, it will be called when the worker returns the result
    this.callbacks[id] = callback;

    // send the request to the worker
    this.worker.postMessage(JSON.stringify(request));
  };

  // create a MathWorker
  var worker = new MathWorker();

  // evaluate an expression via the worker
  worker.eval('12 / (2.3 + 0.7)', function (err, result) {
    document.getElementById('results').innerHTML += 'result: ' + result + '<br>';
  });

</script>

</body>
</html>

File: worker.js

importScripts('http://cdnjs.cloudflare.com/ajax/libs/mathjs/3.18.0/math.min.js');

// create a parser
var parser = math.parser();

self.addEventListener('message', function(event) {
  var request = JSON.parse(event.data),
      result = null,
      err = null;

  try {
    // evaluate the expression
    result = parser.eval(request.expr);
  }
  catch (e) {
    // return the error
    err = e;
  }

  // build a response
  var response = {
    id: request.id,
    result: result,
    err: err
  };

  // send the response back
  self.postMessage(JSON.stringify(response));

}, false);
Fork me on GitHub