我正在阅读一篇文章,其中指出要创建非阻塞/异步函数,setTimeout
的使用至关重要。我认为传递给 setTimeout 的函数在后台运行。然后我在另一篇文章中读到 setTimeout 在函数被触发时确实会阻止事件循环。因此,我尝试了以下功能来测试。
function getit(cb) {
var i = 0;
setTimeout(function() {
while (i < 200000) { i++; console.log(i); }
cb(i);
} , 1000);
console.log(i);
}
getit(function(message) { console.log(message); });
显然,当 1000 毫秒过去并且该执行该函数时,线程被阻塞并且我的浏览器卡住。我的问题是,如果异步代码不应该阻塞线程,那么当函数在时间流逝时执行而不是在后台执行时,这怎么可能?看起来这只是一个延迟,但最终该函数将逐行执行并无论如何都会阻塞循环。有什么我遗漏或困惑的吗?
最佳答案
Node.js执行模型可以用以下代码表示:
function main() {
while(running) {
var timerCb = getNextTimedoutCallback();
if( timerCb ) timerCb(); // execute it
var ioCb = getNextCompleteIOOperationCallback();
if( ioCb ) ioCb(); // execute it
}
}
一切都在单线程中运行。 IO 操作在工作线程中运行,并填充已完成 IO 操作的内部队列。 getNextCompleteIOOperationCallback();
只是从队列中提取已完成的操作。
以同样的方式setTimeout()
简单地将函数及其结束时间推送到计时器队列(按结束时间排序)。并且 getNextTimedoutCallback()
提取下一个过期超时(如果有)。
如您所见,计时器函数或 IO 回调都可以阻止整个过程。 这就是 cooperative multitasking .
关于javascript - setTimeout 阻止事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38176083/