I planned to use setInterval to simply set a variable to false, which would be inspected by the main loop to stop. Example (note: this is an example only, the acutal code is not a while() loop which would be easy to reconstruct, but a quite complex, and long to execute script generated by a closed source software actually):
var running = true;
setInterval(function () {
if (running) {
console.log("Stopping now!");
running = false;
}
}, 100);
while (running) {
// do something ...
}
However it does not seem to work at least firefox drops a "busy script" box after a while. What's the problem with the code above? setInterval() may not be able to run if your script already runs otherwise? I couldn't find an exact specification what setInterval() does exactly.
I would need something like this, since I already have huge (and very long to execute) script, so I thought I will try to stop it after a while, then using setTimeout() to let the browser breath a bit and then continue: as the script itself does know its internal state so it can continue from any point, but it's not an option to modify the script actually ....
If it's not possible with setInterval, is there any alternative to this, without any modification in the "long to execute" code itself?
Thanks!
If it's not possible with setInterval, is there any alternative to this, without any modification in the "long to execute" code itself?
One possibility is to make that a web worker rather than trying to use it on the UI thread. Despite people repeatedly saying so, JavaScript is not single-threaded (JavaScript, the language, is silent on the subject), not even on browsers anymore. In the browser environment, there is one main UI thread, but you can spawn other worker threads (web workers). The worker(s) and the main UI code can communicate via postMessage / onmessage.
Here's an example of a web worker in action. This page uses JavaScript on the UI thread to start a web worker, which runs on a separate thread. The worker runs for 10 seconds, busily updating a counter (this is just to simulate a long-running, calculation-intensive process), and sends updates to the UI thread every second:
Main page:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Worker Example</title>
<style type="text/css">
body {
font-family: sans-serif;
}
</style>
<meta charset="UTF-8">
</head>
<body>
<script>
(function() {
var worker = new Worker("worker.js");
worker.onmessage = function(e) {
display("Worker says " + e.data);
};
display("Starting worker");
worker.postMessage("start");
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
worker.js:
this.onmessage = function(e) {
var counter, lastUpdate, now;
if (e.data === "start") {
// Loop without yeilding for 10 seconds, sending updates
// to the UI every second.
start = lastUpdate = Date.now();
counter = 0;
do {
++counter;
now = Date.now();
if (now - lastUpdate > 1000) {
lastUpdate = now;
this.postMessage(counter);
}
}
while (now - start < 10000);
this.postMessage("Done");
}
};
(You're not required to make the worker wait for a message to start, but it's fairly common.)
The problem is that Javascript is single-threaded. Rewrite your while loop to use setInterval itself and everything should work, since you will release the thread at the end of each loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With