在 JavaScript 库中经常看到这样的代码:
setTimeout(function() {
...
}, 0);
我想知道为什么要使用这样的包装代码。
非常简化:
浏览器是单线程的,并且这个单线程(UI 线程)在渲染引擎和 js 引擎之间共享。
如果您想做的事情需要花费大量时间(我们在这里讨论循环,但仍然如此),它可能会停止(暂停)渲染(流程和绘制)。
在浏览器中,还存在“存储桶”,所有事件首先都会等待 UI 线程完成其正在执行的操作。一旦线程完成,它就会在桶中查找并选择队列中第一个任务。
Using setTimeout
您在延迟后在存储桶中创建一个新任务,并让线程在可用于更多工作时立即处理它。
A story:
0 毫秒延迟后创建函数的新任务
并将其放入桶中。就在那一刻,UI 线程正忙
正在做其他事情,并且桶中还有其他任务
已经。 6ms 后线程可用并获取前面的任务
你的,很好,下一个就是你了。但什么?那是一件大事!它有
就像永远(30毫秒)!
最后,现在线程已经完成了,并得到了你的
任务。
大多数浏览器的最小延迟都大于 0,因此将 0 作为延迟意味着:尽快将此任务放入购物篮。但是告诉 UA 尽快将其放入桶中并不能保证它会在那一刻执行。桶就像邮局,可能还有其他任务排着长队。邮局也是单线程的,只有一个人帮助完成所有任务……对不起客户的任务。你的任务必须和其他人一样排队。
如果浏览器没有实现自己的代码,它将使用操作系统的时钟周期。较旧的浏览器的最小延迟在 10-15 毫秒之间。 HTML5指定 http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers如果延迟小于 4ms,UA 应将其增加到 4ms。据说这是2010 年及以后发布的浏览器之间保持一致 https://developer.mozilla.org/en/DOM/window.setTimeout#Minimum_delay_and_timeout_nesting.
See JavaScript 定时器如何工作 http://ejohn.org/blog/how-javascript-timers-work/约翰·雷西格 (John Resig) 撰写,了解更多详细信息。
Edit:另请参阅事件循环到底是什么? https://www.youtube.com/watch?v=8aGhZQkoFbQ作者:Philip Roberts,来自 JSConf EU 2014。这是所有接触前端代码的人都必须查看的内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)