Molly Harper
Molly Harper

Reputation: 2453

Javascript function stops executing when another interaction occurs

In my code example below I have two buttons that do the following:

1) Clicking button 1 executes a while loop

2) Clicking button 2 executes a log statement

If you click button 1 and then click button 2, button 1 stops executing.

Is it possible to have button 1 continue to execute when another action occurs?

function buttonOneClick() {
  let i = 0;
  while (i < 1000) {
    console.log('index is ', i);
    i++;
  }
}

function buttonTwoClick() {
  console.log('button two clicked');
}
<button type="button" onclick="buttonOneClick()">Click Button One and Start Loop</button>
<button type="button" onclick="buttonTwoClick()">Click Button Two</button>

Upvotes: 2

Views: 163

Answers (1)

muka.gergely
muka.gergely

Reputation: 8329

A solution for "JavaScript multi-threading": you could use webworkers for the problem. Put the code you want to execute in a webworker, that runs in the background (by definition):

Web Workers is a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null). Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

With this solution you can have your function continuously executed, and still have access to other functions.

Note that this is not a traditional webworker in my solution, but an inline webworker.

function buttonOneClick() {
  // create an inline webworker
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], {
    type: "text/javascript"
  })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
}

function buttonTwoClick() {
  console.log('button two clicked');
}
<button type="button" onclick="buttonOneClick()">Click Button One and Start Loop</button>
<button type="button" onclick="buttonTwoClick()">Click Button Two</button>

<script id="worker1" type="javascript/worker">
  // This script won't be parsed by JS engines because its type is javascript/worker.
  self.onmessage = function(e) {
    for (let i = 0; i < 1000; i++) {
      self.postMessage( 'message from worker ' + i)
    }
  };
// Rest of your worker code goes here.
</script>

To check the results, use the real console, and scroll back a some - you'll find your buttonTwoClick() console.log().

One note, though

Don't press Tidy in the snippet - it will mess up the worker, as it cannot "understand" what that is.

Upvotes: 1

Related Questions