我的脚本运行时是否调用了 setInterval 处理程序? [英] Is setInterval handler called while my script running?

查看:29
本文介绍了我的脚本运行时是否调用了 setInterval 处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划使用 setInterval 简单地将一个变量设置为 false,主循环会检查该变量以停止.例子(注意:这只是一个例子,实际代码不是一个容易重构的while()循环,而是一个相当复杂的,实际上一个闭源软件生成的脚本执行时间长):

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 ...
}

但是它似乎不起作用,至少 Firefox 会在一段时间后丢弃一个忙脚本"框.上面的代码有什么问题?如果您的脚本已经运行,则 setInterval() 可能无法运行?我找不到 setInterval() 究竟做了什么的确切说明.

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.

我需要这样的东西,因为我已经有巨大的(并且很长的执行时间)脚本,所以我想我会在一段时间后尝试停止它,然后使用 setTimeout() 让浏览器喘口气然后继续:因为脚本本身确实知道它的内部状态,所以它可以从任何时候继续,但实际上修改脚本不是一个选项......

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 ....

如果 setInterval 无法实现,是否有其他替代方法,而无需对执行时间长"代码本身进行任何修改?

If it's not possible with setInterval, is there any alternative to this, without any modification in the "long to execute" code itself?

谢谢!

推荐答案

如果 setInterval 无法实现,是否有其他替代方法,而无需对执行时间长"代码本身进行任何修改?

If it's not possible with setInterval, is there any alternative to this, without any modification in the "long to execute" code itself?

一种可能性是使其成为网络工作者而不是而不是尝试在 UI 线程上使用它.尽管人们一再这样说,JavaScript 不是单线程(JavaScript,语言,在这个主题上保持沉默),甚至不再在浏览器上.在浏览器环境中,有一个主 UI 线程,但您可以生成其他工作线程(Web 工作线程).工作线程和主 UI 代码可以通过 postMessage/onmessage 进行通信.

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.

这是一个正在运行的网络工作者示例.此页面在 UI 线程上使用 JavaScript 来启动在单独线程上运行的 Web Worker.Worker 运行了 10 秒,忙着更新一个计数器(这只是为了模拟一个长时间运行、计算密集的过程),并且每秒向 UI 线程发送更新:

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:

主页:

<!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.)

这篇关于我的脚本运行时是否调用了 setInterval 处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆