Ran*_*lue 4 javascript settimeout
这是我的测试代码(在这里小提琴):
console.log('Before wait');
setTimeout(function () { console.log('Yo!'); }, 1000);
var start = Date.now();
while (Date.now() < start + 3000) {}
console.log('After wait');
Run Code Online (Sandbox Code Playgroud)
这是Chrome中事件的时间轴:
这种行为是否符合规范?为什么不呢
?
Tom*_*icz 43
JavaScript是单线程的.如果某些代码块使用执行线程,则不能执行其他代码.这意味着您的setTimeout()调用必须等到主执行(具有忙等待while循环的循环)完成.
以下是发生的情况:您计划setTimeout()在一秒钟后执行,然后阻止主线程3秒钟.这意味着你的繁忙循环完成的那一刻,超时已经是2秒太晚了 - 而且JS引擎试图通过尽快调用你的超时来保持同步 - 也就是说,立即.
事实上这个:
while (Date.now() < start + 3000) {}
Run Code Online (Sandbox Code Playgroud)
是JavaScript中最糟糕的事情之一.您持有JavaScript执行线程3秒钟,并且不能执行其他事件/回调.通常,浏览器会在那段时间内"冻结".
延迟setTimeout是相对于调用它的确切时间点.当你还在忙着等待时,它会过期.因此它将在控制返回事件循环的下一瞬间执行.
编辑:
在这一点上,规范有点模糊,但我想这是有意和唯一直接的解释:
setTimeout(函数,毫秒)
此方法在经过指定的毫秒数后调用该函数,直到通过调用clearTimeout取消.这些方法返回一个timerID,可以在后续的clearTimeout调用中取消该间隔.