<html>

<head>
  <title>Web workers</title>
  <link rel="stylesheet" type="text/css" href="./index.css" />
</head>

<body>
  <p>Do a prime number search from <input id="from" value="1"> to <input id="to" value="2000000" size="100">.</p>
  <button onclick="doSearch()" id="searchButton">Start Searching</button>
  <button onclick="cancelSearch()">Cancel</button>

  <div id="primeContainer">
  </div>

  <div id="status"></div>
  <div>
    This example comes from
    <a href="https://medium.com/young-coder/a-simple-introduction-to-web-workers-in-javascript-b3504f9d9d1c">here</a>.
  </div>
  <script id="FindPrimes" type="javascript/worker">
    onmessage = function (event) {
            var primes = findPrimes(event.data.from, event.data.to);
            postMessage(
                {messageType: "PrimeList", data: primes}
            );
        };
        
        function findPrimes(fromNumber, toNumber) {
            // Create an array containing all integers between the two specified numbers.
            var list = [];
            for (var i = fromNumber; i <= toNumber; i++) {
                if (i > 1) list.push(i);
            }
        
            // Test for primes.
            var maxDiv = Math.round(Math.sqrt(toNumber));
            var primes = [];
        
            var previousProgress;
        
            for (var i = 0; i < list.length; i++) {
                var failed = false;
                for (var j = 2; j <= maxDiv; j++) {
                    if ((list[i] != j) && (list[i] % j == 0)) {
                        failed = true;
                    } else if ((j == maxDiv) && (failed == false)) {
                        primes.push(list[i]);
                    }
                }
        
                // Give a progress update.
                var progress = Math.round(i / list.length * 100);
                if (progress != previousProgress) {
                    postMessage(
                        {messageType: "Progress", data: progress}
                    );
                    previousProgress = progress;
                }
            }
        
            return primes;
        }
    </script>
  <script src="./index.js"></script>
</body>

</html>
body {
  font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
  margin: 20px;
}

#primeContainer {
  border: solid 1px black;
  padding: 3px;
  height: 300px;
  max-width: 500px;
  overflow: scroll;
  overflow-x: hidden;
  font-size: x-small;
  margin-top: 20px;
  margin-bottom: 10px;
}

input {
  width: 80px;
}

button {
  padding: 3px;
}

p {
  margin-bottom: 3px;
}

#status {
  color: darkred;
}
var statusDisplay;
var worker;
var searchButton;

window.onload = function () {
  statusDisplay = document.getElementById("status");
  searchButton = document.getElementById("searchButton");
};

function doSearch() {
  // Get the two numbers in the text boxes. This is the search range.
  searchButton.disabled = true;

  var fromNumber = document.getElementById("from").value;
  var toNumber = document.getElementById("to").value;

  // Ordinarily you would give the web worker JavaScript in a separate
  // file, using a line of code like this.
  //worker = new Worker("PrimeWorker.js");

  // Because this example is hosted on CodePen,
  // which doesn't let you use separate JS files,
  // we need to use a workaround to grab the
  // PrimeWorker.js code from the findPrimes() function
  // on this page.
  var blob = new Blob([document.querySelector("#FindPrimes").textContent]);
  blobURL = window.URL.createObjectURL(blob);

  worker = new Worker(blobURL);
  // worker.onmessage = receivedWorkerMessage;
  worker.addEventListener("message", receivedWorkerMessage);
  worker.onerror = workerError;

  worker.postMessage({
    from: fromNumber,
    to: toNumber
  });

  statusDisplay.innerHTML =
    "A web worker is on the job (" + fromNumber + " to " + toNumber + ") ...";
}

function receivedWorkerMessage(event) {
  var message = event.data;

  if (message.messageType == "PrimeList") {
    var primes = message.data;

    // Show the prime number list on the page.
    var primeList = "";
    for (var i = 0; i < primes.length; i++) {
      primeList += primes[i];
      if (i != primes.length - 1) primeList += ", ";
    }
    var displayList = document.getElementById("primeContainer");
    displayList.innerHTML = primeList;

    if (primeList.length == 0) {
      statusDisplay.innerHTML = "Search failed to find any results.";
    } else {
      statusDisplay.innerHTML = "The results are here!";
    }
    searchButton.disabled = false;
  } else if (message.messageType == "Progress") {
    statusDisplay.innerHTML = message.data + "% done ...";
  }
}

function workerError(error) {
  statusDisplay.innerHTML = error.message;
}

function cancelSearch() {
  worker.terminate();
  worker = null;
  statusDisplay.innerHTML = "Search cancelled.";
  searchButton.disabled = false;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.