Call setTimeout without delay
浏览器是单线程的,这个单线程(UI线程)在渲染引擎和js引擎之间共享。如果你想做的事情需要很多时间(我们在谈论循环,但仍然如此),它可能会暂停(停止)渲染(流程和绘制)。在浏览器中还存在一个“桶”,所有事件都首先放入其中,等待UI线程完成其正在做的工作。一旦线程完成,它就会查看桶,并选择排在前面的任务。使用setTimeout可以在延迟后在桶中创建一个新任务,并在线程可以进行更多工作时处理它。一个故事:
在0毫秒的延迟后创建一个新的任务函数,并将其放入桶中。在那个确切的时刻,UI线程正在忙于做其他事情,并且桶中已经有其他任务。经过6毫秒,线程可用,并获取你前面的任务,很好,你是下一个。但是怎么回事?那是一个巨大的任务!它已经很久了(30毫秒)!最后,现在线程完成了,并来执行你的任务。
大多数浏览器都有一个最小延迟,比0大,所以把0作为延迟意味着:尽快把这个任务放入篮子里。但是告诉UA尽快把它放入桶里并不保证它会立即执行。桶就像邮局,可能有很长的其他任务队列。邮局也是单线程的,只有一个人帮助所有任务...抱歉,客户完成他们的任务。你的任务必须像其他人一样排队。
如果浏览器没有实现自己的时钟,它将使用操作系统的时钟。旧的浏览器之间最小延迟为10-15毫秒。HTML5规定,如果延迟小于4毫秒,UA应将其增加到4毫秒。据说这在2010年及以后发布的浏览器中是一致的。
有关更多详细信息,请参见John Resig的《How JavaScript Timers Work》。此外,请观看Philip Roberts在JSConf EU 2014上的《What the heck is the event loop anyway?》这是所有接触前端代码的人必看的。
setTimeout(function(){ // code to be executed after a delay }, 0);
在JavaScript中,我们可以使用setTimeout函数来延迟执行某个代码块。然而,有时候我们希望通过setTimeout来执行一个代码块,但又不希望出现任何延迟,即立即执行。那么为什么会出现这种情况,以及如何解决呢?
出现这种情况有几个原因:
1. 有一些操作你不想立即执行,但希望在不久的将来的某个时间段执行。
2. 你希望在之前注册的setTimeout或setInterval的处理程序运行完之后再执行。
对于第一个原因,如果你有一些操作需要在稍后执行,但不希望立即执行,你可以使用setTimeout函数来设置一个延迟时间。但是,如果你希望立即执行,而不是延迟执行,就需要使用一个非常短的延迟时间,即0毫秒,来达到立即执行的效果。
对于第二个原因,如果你之前已经注册了一个setTimeout或setInterval的处理程序,并且希望在这些处理程序运行完之后再执行一个新的代码块,你也可以使用setTimeout函数来实现。通过将延迟时间设置为0毫秒,可以确保之前的处理程序有足够的时间运行完毕,然后再执行新的代码块。
因此,解决这个问题的方法就是在调用setTimeout时将延迟时间设置为0毫秒。这样可以确保代码块会立即执行,同时也可以让之前注册的setTimeout或setInterval的处理程序有足够的时间运行完毕。