We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从一种基本层面上去理解JavaScript计时器是如何工作的是非常有必要的。因为它们处于单线程的环境里,因此它们的行为并不是那么直观。开始通过测试我们能用来构造并且操控计时器的三个函数开始吧。
var id = setTimeout(fn, delay);
var id = setInterval(fn, delay);
clearInterval(id); clearTimeout(id);
为了从本质上理解计时器的工作原理,我们需要深究一个重要的概念:计时器时延不可靠。因为所有浏览器中的JavaScript都在单线程下执行,异步事件(例如鼠标点击和计时器)只有在执行中存在空隙入口才能运行。最好用一个图表来示范,如下所示:
点击预览大图
这个图中有大量的信息需要理解消化,但是完整的理解它将会给你对于异步的JavaScript如何工作执行有一个清晰的认知。这个图表是一维的:我们有一个竖直的毫秒时刻表(挂钟)。蓝色的块代表正在执行的JavaScript的一部分。举个例子,第一块JavaScript执行了大约18ms,鼠标点击模块执行了大约11ms,诸如此类。
因为JavaScript在一个时刻永远只能执行代码的一部分(由于它的单线程本质)每一个在代码中像这样的块都“阻塞”其他的异步事件的进程。这意味着当异步事件发生(类似一个鼠标点击、激活计时器、或者一个XMLHttpRequest完成),它会排成队列在之后被逐个执行(这个队列设置是如何确切的发生在不同的浏览器上各自不同,所以别想复杂了)。
首先,在第一个JavaScript块中,两个计时器被初始化:一个10ms的setTimeOut和一个10ms的setInterval。在我们真正完成第一块代码之前就决定了计时器何时何地开始激活。需要注意的是,无论怎样,绑定的函数都不会立刻执行(由于线程的原因,没有权利去这样做)。取而代之的是让函数延迟组成队列,为了在下一个空闲的时刻执行。
此外,在这第一个JavaScript块里面我们看到了一个鼠标点击事件产生了。JavaScript回调函数链接了这异步事件(我们永远不知道用户何时可以执行某个操作,因此它被看做是异步的),这个函数无法立刻执行,就像初始计时器一样,会排进队列之后被执行。
在初始的JavaScript块执行结束之后,浏览器立刻提出问题:什么东西等待被执行?在那个时候一个鼠标点击处理程序和一个计时器回调都处于等待中。然后浏览器挑选一个(鼠标点击回调)并且立即执行它。计时器为了被执行会继续等待直到下一个可能的时刻。
需要注意的是,当鼠标点击事件处理程序正在执行的时候,第一个定时器回调也在执行。于是计时器的处理程序进入队列等待下次执行。但是,当定时器再一次被激活时(当计时器的处理程序正在执行时),这一次定时器的处理执行程序被丢弃了。如果你将所有定时器的回调整理成队列形式,在一大块JavaScript代码执行完成得到结果之后,这些定时器会彼此没有时间间隔的执行。除此之外,浏览器会倾向于等待执行队列里面没有定时器的处理程序(产生定时器相关的问题)之后再往队列里面添加定时器。
事实上,我们可以看到当第三个定时器回调函数开始激活时,定时器本身也在执行。这告诉我们一个重要的现象:定时器不关心谁正在执行,它们会任意的排进队列,那意味着回调之前的时间间隔会被挤压掉。
最后,在第二次定时器回调完成了执行,我们能看到JavaScript引擎没有什么需要去执行。这代表着浏览器现在等待着新的异步事件发生。我们在标记的50ms处,定时器又一次被激活,于是得到了新的异步事件。这一次,终于没有什么阻塞它的执行,于是它立即运行。
我们来看下一个例子来更好的诠释setTimeout 和setInterval 之间的不同。
setTimeout
setInterval
setTimeout(function(){ /* Some long block of code... */ setTimeout(arguments.callee, 10); },10);
setInterval(function(){ /* Some long block of code... */ },10);
这两段代码第一眼看上去可能功能上相同,实则不然。显然,setTimeout代码段在前回调执行后至少10ms执行(只会多,不会少)。setInterval会尝试每10ms执行,不管上一次回调是否执行完成。
我们从这儿学到了很多,总结一下。
所有这些都是很重要的。清楚JavaScript引擎如何工作,尤其是在大量的异步事件发生时,为构造健壮的应用程序代码打下坚实的基础。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
写在前面,这篇博客,哪里翻译的不好请见谅。(ORZ ,瑟瑟发抖),巨佬(John Resig) 原文
从一种基本层面上去理解JavaScript计时器是如何工作的是非常有必要的。因为它们处于单线程的环境里,因此它们的行为并不是那么直观。开始通过测试我们能用来构造并且操控计时器的三个函数开始吧。
var id = setTimeout(fn, delay);
--初始化一个计时器,其会在一段时间间隔后调用的特殊函数。这个函数会返回一个唯一的ID,计时器在之后可以通过ID取消。var id = setInterval(fn, delay);
--与setTimeout很像,但是会继续调用函数(每时延一段时间)直到它被取消。clearInterval(id); clearTimeout(id);
--接收一个计时器ID(被上述任一函数所返回)并且中断ID对应的计时器。为了从本质上理解计时器的工作原理,我们需要深究一个重要的概念:计时器时延不可靠。因为所有浏览器中的JavaScript都在单线程下执行,异步事件(例如鼠标点击和计时器)只有在执行中存在空隙入口才能运行。最好用一个图表来示范,如下所示:
点击预览大图
这个图中有大量的信息需要理解消化,但是完整的理解它将会给你对于异步的JavaScript如何工作执行有一个清晰的认知。这个图表是一维的:我们有一个竖直的毫秒时刻表(挂钟)。蓝色的块代表正在执行的JavaScript的一部分。举个例子,第一块JavaScript执行了大约18ms,鼠标点击模块执行了大约11ms,诸如此类。
因为JavaScript在一个时刻永远只能执行代码的一部分(由于它的单线程本质)每一个在代码中像这样的块都“阻塞”其他的异步事件的进程。这意味着当异步事件发生(类似一个鼠标点击、激活计时器、或者一个XMLHttpRequest完成),它会排成队列在之后被逐个执行(这个队列设置是如何确切的发生在不同的浏览器上各自不同,所以别想复杂了)。
首先,在第一个JavaScript块中,两个计时器被初始化:一个10ms的setTimeOut和一个10ms的setInterval。在我们真正完成第一块代码之前就决定了计时器何时何地开始激活。需要注意的是,无论怎样,绑定的函数都不会立刻执行(由于线程的原因,没有权利去这样做)。取而代之的是让函数延迟组成队列,为了在下一个空闲的时刻执行。
此外,在这第一个JavaScript块里面我们看到了一个鼠标点击事件产生了。JavaScript回调函数链接了这异步事件(我们永远不知道用户何时可以执行某个操作,因此它被看做是异步的),这个函数无法立刻执行,就像初始计时器一样,会排进队列之后被执行。
在初始的JavaScript块执行结束之后,浏览器立刻提出问题:什么东西等待被执行?在那个时候一个鼠标点击处理程序和一个计时器回调都处于等待中。然后浏览器挑选一个(鼠标点击回调)并且立即执行它。计时器为了被执行会继续等待直到下一个可能的时刻。
需要注意的是,当鼠标点击事件处理程序正在执行的时候,第一个定时器回调也在执行。于是计时器的处理程序进入队列等待下次执行。但是,当定时器再一次被激活时(当计时器的处理程序正在执行时),这一次定时器的处理执行程序被丢弃了。如果你将所有定时器的回调整理成队列形式,在一大块JavaScript代码执行完成得到结果之后,这些定时器会彼此没有时间间隔的执行。除此之外,浏览器会倾向于等待执行队列里面没有定时器的处理程序(产生定时器相关的问题)之后再往队列里面添加定时器。
事实上,我们可以看到当第三个定时器回调函数开始激活时,定时器本身也在执行。这告诉我们一个重要的现象:定时器不关心谁正在执行,它们会任意的排进队列,那意味着回调之前的时间间隔会被挤压掉。
最后,在第二次定时器回调完成了执行,我们能看到JavaScript引擎没有什么需要去执行。这代表着浏览器现在等待着新的异步事件发生。我们在标记的50ms处,定时器又一次被激活,于是得到了新的异步事件。这一次,终于没有什么阻塞它的执行,于是它立即运行。
我们来看下一个例子来更好的诠释
setTimeout
和setInterval
之间的不同。这两段代码第一眼看上去可能功能上相同,实则不然。显然,setTimeout代码段在前回调执行后至少10ms执行(只会多,不会少)。setInterval会尝试每10ms执行,不管上一次回调是否执行完成。
我们从这儿学到了很多,总结一下。
所有这些都是很重要的。清楚JavaScript引擎如何工作,尤其是在大量的异步事件发生时,为构造健壮的应用程序代码打下坚实的基础。
The text was updated successfully, but these errors were encountered: