易云巢做营销型网站,购物网站名称,wordpress管理员密码忘记,网络项目推广平台作为入门者来说。了解JavaScript中timer的工作方式是非常重要的。通常它们的表现行为并非那么地直观#xff0c;而这是由于它们都处在一个单一线程中。让我们先来看一看三个用来创建以及操作timer的函数。var id setTimeout(fn, delay); - 初始化一个单一的timer#xff0c… 作为入门者来说。了解JavaScript中timer的工作方式是非常重要的。通常它们的表现行为并非那么地直观而这是由于它们都处在一个单一线程中。让我们先来看一看三个用来创建以及操作timer的函数。 var id setTimeout(fn, delay); - 初始化一个单一的timer这个timer将会在一定延时后去调用指定的函数。这个函数setTimeout将返回一个唯一的ID我们能够通过这个ID来取消timer。 var id setInterval(fn, delay);- 与setTimeout类似仅仅只是它会持续地调用指定的函数每次都有一个延时直到timer被取消为止。 clearInterval(id);, clearTimeout(id);- 接受一个timer的ID由上述的两个函数返回的而且停止timer的回调事件。 要弄明确这个定时器内部是怎么工作的有一个非常重要的概念须要被提出来 1 定时器延迟是不准确的(guaranteed).由于全部的javascript 浏览器代码仅仅有一个单线程运行而且那些异步事件如鼠标点击事件和定时器仅仅会在出现线程空暇的时候去会运行。这有一个图表演示。例如以下 这里有非常多信息在这个图中须要去理解。可是全然理解它之后。你会对javascript中异步机制有一个清楚的认识。这个图是一维的: 垂直方向我们用毫秒单位来标记这个时间。这个蓝色的方块代表这个正在被运行的javascript代码。比如这第一个被运行的javascript代码大约花了18毫秒这个鼠标事件块大约花费了11毫秒等等。 由于javascript 引擎永远仅仅会执行一个片段的代码在同一个时间由于这个单线程机制那么这时每个代码块将会堵塞blocking别的异步事件的执行。 这意味着当一个异步事件被调用比如当一个鼠标点击一个定时器触发firing,或者一个xmlhttprequest 过程完毕它将会被增加到队里。并延迟运行(至于详细怎样被入到队列中不同的浏览器有不同的实现。我们这里仅仅考虑简单的情况) 从一開始在第一个javasript中有两个定时器被初始化了 一个10 毫秒的 setTimeout时间和一个10 毫秒的setInterval事件这里注意只不过初始化亦或叫作定义。 由于这个定时器開始的时间和位置。导致它们在第一个javascript块完毕前就已经真正被调用(这里的调用并不是直接运行这里须要注意,能够理解为仅仅是准备调用把该回调方法增加到队列)了。注意不管怎么样however。定时器都不会立马运行(由于线程没有空暇的原因它没办法直接运行)。相反。这个被延迟的方法会被增加到队列中在某个能够运行的时刻线程空暇的时刻运行。 另外一点在第一个javascript块中。我们能够看到另一个鼠标事件被触发了。这个javascript 回调方法被关联到一个异步事件 (没人知道用户什么时候做这个动作。所以它被觉得是异步的)这个异步事件也不会立马运行和上面的定时器一样。也会被增加到队列中。 在第一个javascript 块运行结束之后javascript 引擎就会立马问一个问题 还有什么在等待被运行的代码么 那么这个时间有一个鼠标事件回调和定时器回调同一时候在等待。这个浏览器立即挑选一个(从图中看。是鼠标事件回调)立马运行。这个定时器继续等待直到下一个可能的时刻。 注意一点在这个这个鼠标事件处理函数正在被运行的同一时候第一个interval 回调函数也会调用。正如前面提到的定时器一样它的回调方法会被增加到队列中。然而。注意当这个interval再一次被调用这个时候这个定时器的回调方法正在被运行。那么这个时候。这个interval 的回调方法将会被删除drop。 假设因为主线程须要运行非常长时间的代码块导致你在队列中增加了非常多个回调方法那么当这个主线程结束之后一连串的回调函数连续运行没有间隔直到结束。比較好的做法是临时让浏览器歇息等待一会。让队列中没有Interval回调。 我们在看到一些情况在第三个interval 回调方法触发的时候。inteval自身正在运行这里应该是下在运行第二个interval没有结束。这里给我们展示了一个重要的信息 interval 不会去关心当前的线程如今运行什么它们会把自己的回调方法增加到队列中在不论什么情况下即使它会让两个间隔的回调方法之间的时间降低。 最后在第二个interval图中应该是第三个这里应为中间有一个被drop掉了被 运行完之后javasript引擎中已经没有东西能够用来运行了。这也就是说。浏览器如今正在等一个新的异步事件须要去触发(occur)。在第50毫秒的时候再一次触发了inteval回调。这个时候。已经没有东西去堵塞它的运行。所以它增加到队列中之后就立马运行了。 接下来让我们看一个样例更好的理解setTimeout与setInterval的差别 setTimeout(function(){/* Some long block of code... */setTimeout(arguments.callee, 10);}, 10);setInterval(function(){/* Some long block of code... */}, 10); 这两段代码可能在功能的实现上很的相似。不经意一看他们是全然一样的。尤其是这个setTimeout代码会在上一个回调函数运行之后至少隔10毫秒再运行一次回调方法它可能会超过10毫秒但不会少于10毫秒。可是setInteval 却会尝试10毫秒就运行一个回调函数不会去管上一个回调是什么时候运行的。 These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed. 这里有一些东西是我们从这里学到的做一个总结 1 javascript引擎只唯独一个单线程正在运行的异步事件会增加到队列等待。 2 setTimeout与setInterval 是运行异步回调方法从根本上不一样的。 3 假设一个须要马上运行的定时器被堵塞了。它将被延迟运行。知道下一次线程空暇那么被延迟的时间会超过定时器定义的时间 4 interval 可能会没有延迟的连续运行回调方法假设主线程了运行一个足够长的代码比定时的延迟长 全部的这些都是很重要的知识对于了解javascript引擎是怎样工作的。特别是对于大数量的回调事件发生的时候为我们建立更好的应用代码建立好的基础。 ---------------------------------------------------------------------------------------------------- 原文出自jQuery的作者John Resig。 地址http://ejohn.org/blog/how-javascript-timers-work/#postcomment 转载于:https://www.cnblogs.com/claireyuancy/p/6956876.html