在javascript中有两种(最常用的)类型的计时器函数setTimeout和setInterval (other)
这两个方法具有相同的签名。它们以回调函数和延迟时间为参数。
setTimeout在延迟后只执行一次,而setInterval在每延迟几毫秒后都会继续调用回调函数。
这两个方法都返回一个整数标识符,可用于在计时器过期之前清除它们。
clearTimeout和clearInterval这两个方法都接受从上面的函数setTimeout和setInterval返回的整数标识符
例子:
setTimeout
alert("before setTimeout");
setTimeout(function(){
alert("I am setTimeout");
},1000); //delay is in milliseconds
alert("after setTimeout");
如果你运行上面的代码,你会看到它在setTimeout之前发出警报,然后在setTimeout之后,最后它在1秒(1000ms)后发出警报I am setTimeout
你可以从例子中注意到的是setTimeout(…)是异步的,这意味着它不会等待计时器结束后再执行下一个语句,即alert("after setTimeout");
例子:
setInterval
alert("before setInterval"); //called first
var tid = setInterval(function(){
//called 5 times each time after one second
//before getting cleared by below timeout.
alert("I am setInterval");
},1000); //delay is in milliseconds
alert("after setInterval"); //called second
setTimeout(function(){
clearInterval(tid); //clear above interval after 5 seconds
},5000);
如果你运行上面的代码,你会看到它在setInterval之前发出警报,然后在setInterval之后,最后它在1sec (1000ms)后发出警报I am setInterval 5次,因为setTimeout在5秒后清除定时器,否则每1秒你就会收到警报I am setInterval unlimited。
浏览器内部如何做到这一点?
我简单解释一下。
要理解这一点,你必须了解javascript中的事件队列。在浏览器中实现了一个事件队列。当一个事件在js中被触发时,所有这些事件(如点击等)。被添加到此队列。当你的浏览器没有什么要执行时,它会从队列中获取一个事件并逐个执行。
现在,当你调用setTimeout或setInterval时,你的回调会在浏览器中注册到一个计时器,它会在给定的时间过期后添加到事件队列中,最终javascript从队列中获取事件并执行它。
这是因为javascript引擎是单线程的,一次只能执行一件事。所以,他们不能执行其他javascript和跟踪你的计时器。这就是为什么这些计时器注册到浏览器(浏览器不是单线程的),它可以跟踪计时器,并在计时器过期后在队列中添加一个事件。
setInterval也会发生同样的情况,在这种情况下,事件会在指定的时间间隔后一次又一次地添加到队列中,直到它被清除或浏览器页面刷新。
请注意
传递给这些函数的延迟参数是最小延迟
执行回调的时间到了。这是因为在计时器过期之后
方法执行的队列中添加事件
Javascript引擎,但回调的执行取决于你的
事件在队列中的位置,因为引擎是单线程的
将逐个执行队列中的所有事件。
因此,你的回调有时可能需要超过指定的延迟时间才能被调用,特别是当你的其他代码阻塞线程,没有给它时间来处理队列中的内容时。
javascript是单线程的。所以,如果你阻塞线程很长时间。
像这样的代码
while(true) { //infinite loop
}
您的用户可能会收到一条消息,说页面没有响应。