cleartimeout JS 用setTimeout 那本身的函数不就永远不会终止吗
大家好,今天我将为大家揭秘cleartimeout和JS 用setTimeout 那本身的函数不就永远不会终止吗的奥秘,希望我的分享能给你带来新的启发和知识。
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的回调事件。(点击查看大图)由于JavaScript向来都只能在同一时间执行一块代码(这是由它单线程的本质决定的),所以每一个代码块都阻塞了其他的异步事件。这意味着当异步事件发生时(比如鼠标点击、timer触发或者是XMLHttpRequest完成),这些事件将进入到一个队列中等待执行(队列的实现方法因浏览器而异,我们在此只讨论一个简化的情况)。刚开始,在第一个JavaScript块中,有两个timer被初始化了:一个10ms的setTimeout和一个是10ms的setInterval。由于timer(这里的timer指setTimeout中的timer,而下文中的interval则指setInvertal中的timer)开始的时间,实际上它在第一个代码块结束前就已经触发了。然而请注意,它并不会马上执行(事实上由于单线程的存在,它也无法做到马上执行)。相反的,这个被延期执行的函数进入队列中,等待在空闲的时候被执行。当第一个JavaScript块被执行完之后,浏览器问了一个问题:有正在等待被执行的代码吗?在这个例子中,鼠标点击事件和time事件都正在队列中等待。于是浏览器选了一个(鼠标点击事件),然后马上执行它。而timer只能继续等下去。注意当鼠标点击事件正在执行的时候第一次的interval事件也触发了,与timer一样,它的事件也进入队列等待之后执行。然而,注意,当interval再次触发的时候(这个时候timer的事件正在执行),这一次它的事件被丢弃了。如果你在一个大的JavaScript代码块正在执行的时候把所有的interval回调函数都囤起来的话,其结果就是在JavaScript代码块执行完了之后会有一堆的interval事件被执行,而执行过程中不会有间隔。因此,取代的作法是浏览器情愿先等一等,以确保在一个interval进入队列的时候队列中没有别的interval。让我们来看一个例子,这个例子更好地阐释了setTimeout和setInveral之间的区别。 setTimeout(function(){/*一个很长的代码块*/setTimeout(arguments. callee,10);},10);我们在此学到了很多,让我们重述一下: JavaScript引擎只有一个线程,这使得异步事件必需列队等待执行。 setTimeout和如果一个timer在将要执行的时候被阻塞,它将会等待下一个时机(比预期的延时要长)。
JS 用setTimeout 那本身的函数不就永远不会终止吗
首先,setTimeout是可以取消的,可以不让其永远不终止,方法如下:
vartimer=null;
functionf(){
alert("k");
timer=setTimeout(f,1000);
}
//在另外一个函数中,在某种条件下,取消之前的定时器
clearTimeout(timer);
这样,timer就不再执行了,也就不会再次调用函数f,生成新的定时器。
其次,关于内存,js类似于java有垃圾回收机制,一些不会再次用到的变量等,会被清理。只要是作用域不逃出函数f的,函数f执行完毕后,js总是有办法将其销毁,当然不一定百分百销毁。这样的话,内存怎么会越来越多呢?只有函数f在执行的时候会多一些,但随即又会被清理的。
最后,即便没有clearTimeout,在浏览器关闭的时候,一切都会消失的。
要提醒的是,如果函数f里在不停的创建对象,而且在函数f执行完毕后,这些对象又是被引用的,确实会有内存被越来越多的占用。
好了,文章到此结束,希望可以帮助到大家。