javascript - 我的脚本运行时是否调用了 setInterval 处理程序?

标签 javascript setinterval

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

var running = true;
setInterval(function () {
  if (running) {
    console.log("Stopping now!");
    running = false;
  }
}, 100);

while (running) {
  // do something ...
}

但是它似乎不起作用,至少 firefox 会在一段时间后掉落一个“繁忙的脚本”框。上面的代码有什么问题?如果您的脚本已经运行,setInterval() 可能无法运行?我找不到 setInterval() 的确切功能的确切说明。

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

如果不能使用 setInterval,是否有其他替代方案,而不对“执行时间长”的代码本身进行任何修改?

谢谢!

最佳答案

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

一种可能是将其设为 web worker而不是试图在 UI 线程上使用它。尽管人们反复这么说,但 JavaScript 不是是单线程的(JavaScript 这种语言对这个主题只字未提),甚至在浏览器上也不是。在浏览器环境中,有一个主要的 UI 线程,但您可以生成其他工作线程(网络 worker )。 worker(s) 和主 UI 代码可以通过 postMessage/onmessage 进行通信。

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

主页:

<!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");
    }
};

(您不需要让 worker 等待消息开始,但这很常见。)

关于javascript - 我的脚本运行时是否调用了 setInterval 处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22833063/

相关文章:

Javascript 点击事件触发两次,即使使用 stopPropagation

javascript - 如何将动态 json 加载到 jquery 数据表

javascript - 将 SVG 下载为 PNG 图像

Javascript - 在间隔运行的函数内调用时无法使用对象方法?

javascript - 使用 requestAnimationFrame() 作为 setInterval() Javascript

jquery - setInterval 和 setTimeout

javascript - 通过连接两个数组创建新数组

javascript - 在全局范围内声明两个同名函数时,第二个函数将被执行

javascript - ReferenceError SetInterval 未定义

javascript - 如何连续将盒子变成随机颜色