[英]When does a javascript settimeout or setinterval function stop?
[英]Why setInterval function cannot stop setTimeOut from running?
我正在学习 Javscript 并尝试了这段代码:
var a=true;
let c=0;
setTimeout(()=>{
console.log("a is false");
},2000);
setInterval(()=>{
console.log(c++);
},200)
我在想这段代码在执行时会产生一个无限循环,但事实并非如此。
由于 JS 是一种单线程语言,我们让 setInterval 每 200 毫秒运行一次,因此它停留在主线程中。2 秒后 setTimeout 应该执行,但由于 setInterval 在那一刻运行,主线程应该被 setInterval 占用。但仍然setTimeout function 被执行,我无法理解..
单线程并不意味着您只有一个执行上下文。 JS 是事件驱动的,虽然不是多线程的,但有一个协调器(称为事件循环),它确保函数调用在它们应该发生的时候发生。
在您的情况下,setInterval 计划每 200 毫秒运行一次,并且如果已计划(例如您的 setTimeout),则不会阻止任何其他代码运行。
这两段代码在同一个线程中运行,并由事件循环正确调度。
另外:你确实有一个无限循环。 setInterval
function 永远不会停止。
考虑一下这是代码:
var a=true&&false;
let c=0+1;
setTimeout(function1,1000);
setInterval(function2, 200);
CallStack是执行JS的栈
回调队列是异步代码准备执行时排队的队列
在调用栈和回调队列之间是非常有名的事件循环; 它是一个不断监视队列的东西,如果执行调用栈为空,就将队列顶部的东西传递给栈
时间 | 代码执行 |
---|---|
1毫秒 | “var a=true&&false;” 被移动到 CallStack 并立即执行 |
2毫秒 | “令 c=0+1;” 被移动到 CallStack 并立即执行 |
3毫秒 | “设置超时(函数 1,1000);” 被移动到 CallStack 并立即执行; 但是这里,执行是将function1交给WebAPI setTimeout; setTimeout API 此时启动一个2000ms的定时器 |
4毫秒 | “设置间隔(函数 2,200);” 被移动到 CallStack 并立即执行; 但是这里,执行是将function2交给WebAPI setInterval; setInterval API 此时启动一个200ms的定时器 |
5毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
204毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
205毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
404毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
405毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
604毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
605毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
804毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
805毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
1003毫秒 | setTimeout 将 function1 添加到回调队列; Event循环在回调队列中找到function1,立即交给callStack执行; console.log("a 为假"); function1 被执行 |
1004毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
1005毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
1204毫秒 | setInterval 将 function2 添加到回调队列; Event循环在回调队列中找到function2,立即交给callStack执行; 控制台日志(C++); 函数 2 被执行 |
1205毫秒 | No Code in CallStack and Eventloop 在回调队列中找不到任何东西; 所以,没有什么可执行的 |
... | ... |
注意在 1003、1004 和 1005 毫秒处发生的情况。 这就是它的工作原理。 关键是非阻塞 I/0。 在这种情况下,Out I/0 是 webApi setTimeout 和 setInterval
PS - 我在代码行 1 和 2 中添加了表达式,因为理想情况下声明不会占用执行时间。 实际上,表达式执行在现代操作系统中花费的时间远远少于 1 毫秒。 这样做只是为了简化目的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.