Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 脚本运行时是否调用setInterval处理程序?_Javascript_Setinterval - Fatal编程技术网

Javascript 脚本运行时是否调用setInterval处理程序?

Javascript 脚本运行时是否调用setInterval处理程序?,javascript,setinterval,Javascript,Setinterval,我计划使用setInterval将一个变量简单地设置为false,主循环将检查该变量以停止。示例(注意:这只是一个示例,acutal代码不是一个容易重建的while()循环,而是一个非常复杂的、很长的时间来执行由封闭源代码软件生成的脚本): 然而,它似乎不起作用,至少firefox在一段时间后删除了一个“忙脚本”框。上面的代码有什么问题?如果脚本已经运行,setInterval()可能无法运行,否则?我找不到setInterval()的确切功能规范 我需要这样的东西,因为我已经有一个巨大的(而且

我计划使用setInterval将一个变量简单地设置为false,主循环将检查该变量以停止。示例(注意:这只是一个示例,acutal代码不是一个容易重建的while()循环,而是一个非常复杂的、很长的时间来执行由封闭源代码软件生成的脚本):

然而,它似乎不起作用,至少firefox在一段时间后删除了一个“忙脚本”框。上面的代码有什么问题?如果脚本已经运行,setInterval()可能无法运行,否则?我找不到setInterval()的确切功能规范

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

如果setInterval无法实现,那么在不修改“long to execute”代码本身的情况下,是否还有其他方法


谢谢

问题在于Javascript是单线程的。重写
while
循环以使用
setInterval
本身,一切都应该正常,因为您将在每个循环结束时释放线程

如果setInterval无法实现,那么在不修改“long to execute”代码本身的情况下,是否还有其他方法

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

下面是一个网络工作者的例子。此页面在UI线程上使用JavaScript启动web 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>

工人示例
身体{
字体系列:无衬线;
}
(功能(){
var-worker=new-worker(“worker.js”);
worker.onmessage=函数(e){
显示(“工人说”+e.数据);
};
显示(“起始工人”);
worker.postMessage(“开始”);
功能显示(msg){
var p=document.createElement('p');
p、 innerHTML=字符串(msg);
文件.正文.附件(p);
}
})();
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");
    }
};
this.onmessage=函数(e){
var计数器,最近更新,现在;
如果(如数据==“开始”){
//循环10秒钟,不显示yeilding,发送更新
//每隔一秒钟就可以打开UI。
start=lastUpdate=Date.now();
计数器=0;
做{
++计数器;
now=Date.now();
如果(现在-最新更新>1000){
lastUpdate=now;
这是邮政信息(柜台);
}
}
而(现在-开始<10000);
本.邮递信息(“完成”);
}
};

(您不需要让工人等待消息启动,但这是相当常见的)。

< P>您应该考虑使用或编写异步代码。

或者你可以修改你的代码

var running = true;
var past = Date.now();
while (running) {
    // do heavy calculations ...



    if ((Date.now() - past) > 10) {
        running = false;
    }
}
当然,阻塞循环不是个好主意,但我不认为有什么好方法可以满足需求:

如果setInterval无法实现,那么在“long to execute”代码本身中是否有替代方法,而不进行任何修改


JavaScript在单线程事件循环中运行。这意味着当您的代码正在运行时,其他代码无法运行。这就是您的回调无法执行的原因

您还可以通过将while(运行)设置为异步来解决这个问题。考虑以下事项:

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

var work = setInterval(function() {
    if (running) {
        // do something
    } else {
        clearInterval(work);
    }
}, 1);

别忘了打电话给clearInterval

循环时应使用setTimeout或setInterval。JS在单线程中运行,所以无限循环将冻结您的浏览器

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

(function loop(){
    // Do yours loop stuff
    if( running ){
       setTimeout(loop, 0);
    }
})();

…但实际上,这不是修改脚本的选项。嗯,有个问题。是的,它是。。。因为它是由一个软件生成的,而且不是一直都是一样的。该软件是一个封闭源代码的东西:(@LGB:while循环是原始脚本的一部分,对吗?好吧,我的错,它只是一个非常愚蠢的示例/测试脚本,而不是实际的(非常庞大和复杂)。请阅读我为T.J.Crowder的答案所做的评论。很抱歉造成混淆。“或者你可以修改你的代码。”等待10毫秒的繁忙循环有什么意义?Worker的建议很好,但下面的代码示例不是。@filmor:我的示例旨在测试我是否可以这样做的理论。如果我的想法可行,我想尝试一下这个简单的测试示例。它没有。谢谢,web Worker似乎是一个很好的解决方案。尽管在我的示例中,我编写了一个simpe while()循环很容易重建,实际执行的长脚本不是这样的,也不太可能修改它,因为它是一个封闭源代码软件生成的JS代码,只发出JS文件(如果再次生成该文件,甚至不一样)。也许把它放到工作线程中会有效果,我会试试。@LGB:啊,我明白了。我以为
循环在等待另一个代码完成(不起作用:-))。我已经删除了第一段。最好的,
var running = true;
setInterval(function(){
   if(running){
      console.log('Stopping now!');
      running = false;
   }
}, 100);

(function loop(){
    // Do yours loop stuff
    if( running ){
       setTimeout(loop, 0);
    }
})();