HTML5学堂:计时器这个东西,看上去很简单,但是可以拓展挖掘的东西却有很多。对于计时器的基本描述(setInterval与setTimeout)基本名词要规范,如“递归”,文字内容描述应当清晰易于理解,而不是含糊不清。对于区别,并不是仅仅说出运行上的特点,还应当能够说出如何应用以及对性能的影响。对于运行上有可能出现的问题,也能够阐述出来。
计时器分为两类,一种是“在间隔设置了的时间之后,运行相应的函数”,即setTimeout,而另一种是“每隔一段设定的时间间隔,就运行一次相应的函数”。我们可以使用将setTimeout的代码放置到函数内,然后通过对函数的递归调用,而实现类似于setInterval的效果。
JavaScript的运行是单线程运行,因此,严格意义上来讲,上面的基本阐述当中并不是足够的严谨。应该是说,在运行本行代码的时候,将定时器的代码添加到了运行队列当中,而不是何时执行/运行代码。此时需要等到当前“事件处理程序”运行之后再去执行定时器代码。换句话说,就是,并非是设置的毫秒数后就执行定时器代码,执行的时间是有可能提前/延后的。
为方便理解,书写一个例子。假设有如下这段函数,如果认为点击事件的处理程序需要运行200毫秒,从函数开始运行直到设置计时器代码,需要花费10毫秒,计时器设置为150毫秒后运行函数功能,那么相当于是在160毫秒的位置设置了定时器代码,而这段在200毫秒的位置才进行了执行。
欢迎沟通交流~HTML5学堂
针对setInterval,JavaScript引擎进行了处理。之所以处理,在于定时器中代码内容的执行时间有可能会大于间隔时间。也就是说,在代码被再次添加到队列之前,还没与完成执行,从而导致连续运行多次。因此,JavaScript引擎进行了相关处理,仅当队列中没有该定时器的任何其他代码实例时,才能够将定时器代码添加到队列。
由于线程方面的因素,如果使用setInterval之后,可能会造成的问题以及问题规避:1)某些间隔会被跳过;——这也就能够解释如果我们将setInterval中的时间间隔设置为1-10,然后通过位置的变化去实现滚动类效果,会发现滚动块不能像我们希望的那么快的运动。2)多个定时器的代码执行之间的间隔可能会比预期的小。
依旧举个例子:
内联书写setInterval时,由于匿名函数被定义于全局中,不能够计时器的清除,因此很容易造成内存泄露。
JavaScript引擎是单线程的,强制所有的异步事件排队等待执行。
setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同。
如果一个计时器被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些)。
如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔。
欢迎沟通交流~HTML5学堂