Jag*_*gga 3 javascript event-loop
setInterval(function(){console.log("hello")},2000);
while(true){}
Run Code Online (Sandbox Code Playgroud)
"你好"永远不会被打印出来.我认为事件循环在不同的线程中运行,但是在这里看起来像'while循环'阻止了'事件循环'的执行.
有人可以对此有所了解吗?
我对js非常天真,如果问题太基础,那就很抱歉.
你必须明白
浏览器内部如何设置setTimeout?
我将简要解释一下.
要了解更多相关信息
以下是Philip Roberts在jsconf2014中对事件循环的更详细说明
此外,要看到这个过程在行动中有一个很好的工具,看看放大镜
要了解您必须了解javascript中的事件队列.在浏览器中实现了事件队列.每当在js中触发事件时,所有这些事件(如点击等等)都会添加到此队列中.当您的浏览器无法执行任何操作时,它会从队列中获取事件并逐个执行.
现在,当你打电话setTimeout或setInterval你的回调被注册到浏览器中的计时器,它会在给定的时间到期后被添加到事件队列中,最终javascript从队列中获取事件并执行它.
发生这种情况是因为javascript执行是单线程的,并且它们一次只能执行一件事.因此,他们无法执行其他JavaScript并跟踪您的计时器.这就是为什么这些计时器在浏览器中注册(浏览器不是单线程)并且它可以跟踪计时器并在计时器到期后在队列中添加事件.
同样的情况setInterval只发生在这种情况下,事件会在指定的时间间隔后一次又一次地添加到队列中,直到它被清除或浏览器页面刷新为止.
注意
传递给这些函数的延迟参数是执行回调的最小延迟时间.这是因为在计时器到期后,浏览器将事件添加到队列以由javascript引擎执行,但回调的执行取决于您在队列中的事件位置,并且由于引擎是单线程的,它将执行所有事件.队列一个接一个.
因此,当您的其他代码阻塞线程并且没有给它时间处理队列中的内容时,您的回调可能需要花费超过指定的延迟时间来特别调用.
正如我提到的,javascript是单线程.所以,如果你长时间阻止线程.
喜欢这段代码
while(true) { //infinite loop
}
Run Code Online (Sandbox Code Playgroud)
您的用户可以得到一个消息,说页面不响应.
在这里,您的setTimeout活动永远不会执行.
非阻塞 while 循环:
let done = false;
setTimeout(() => {
done = true
}, 5);
const eventLoopQueue = () => {
return new Promise(resolve =>
setImmediate(() => {
console.log('event loop');
resolve();
})
);
}
const run = async () => {
while (!done) {
console.log('loop');
await eventLoopQueue();
}
}
run().then(() => console.log('Done'));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1194 次 |
| 最近记录: |