javascript setTimeout
和setInterval
(其他()中
这两种方法都具有相同的签名。他们以回调函数和延迟时间为参数。
setTimeout
延迟后仅执行一次,而 setInterval
在每个延迟毫秒后仍继续调用回调函数。
这两种方法都返回一个整数标识符,可用于在计时器到期之前清除它们。
clearTimeout
并且clearInterval
这两种方法都采用从上述函数返回的整数标识符,setTimeout
并且setInterval
例:
setTimeout
alert("before setTimeout");
setTimeout(function(){
alert("I am setTimeout");
},1000); //delay is in milliseconds
alert("after setTimeout");
如果运行上面的代码,您将看到它发出警报before setTimeout
,然后after setTimeout
最终发出警报I am setTimeout
在1秒(1000毫秒)后
您可以从示例中注意到,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);
如果运行上面的代码,您将看到它发出警报before setInterval
,然后after setInterval
最终I am setInterval
在1秒(1000毫秒)后发出5次警报,因为setTimeout在5秒后清除了计时器,否则每1秒钟就会发出警报I am setInterval
无限。
浏览器内部如何运作?
我将简要解释。
要了解您必须了解JavaScript中的事件队列。在浏览器中实现了一个事件队列。每当js中触发一个事件时,所有这些事件(如click等)都会添加到此队列中。当您的浏览器没有什么要执行时,它将从队列中获取一个事件并逐一执行它们。
现在,当你打电话 setTimeout
或setInterval
您的回调在浏览器中注册一个计时器,并在给定时间到期后将其添加到事件队列中,并最终javascript从队列中获取事件并执行该事件。
发生这种情况是因为javascript引擎是单线程的,并且它们一次只能执行一件事。因此,他们无法执行其他JavaScript并跟踪您的计时器。这就是为什么这些计时器是在浏览器中注册的(浏览器不是单线程的),并且它可以跟踪计时器并在计时器到期后在队列中添加事件。
setInterval
仅在这种情况下,会发生同样的情况,即在指定的时间间隔后将事件一次又一次地添加到队列中,直到事件被清除或刷新浏览器页面为止。
注意
传递给这些函数的delay参数是执行回调的最短延迟时间。这是因为在计时器到期后,浏览器将事件添加到要由JavaScript引擎执行的队列中,但是回调的执行取决于您事件在队列中的位置,并且由于引擎是单线程的,它将在其中执行所有事件。队列一个接一个。
因此,当您的其他代码阻塞线程并且没有给它时间来处理队列中的内容时,回调有时需要花费比指定的延迟时间更多的时间来专门调用。
正如我提到的,javascript是单线程。因此,如果您长时间阻塞线程。
像这样的代码
while(true) { //infinite loop
}
您的用户可能会收到一条消息,指出页面没有响应。
setTimeout(function(){/*YourCode*/},1000);