开发中经常使用setTimeout进行一些延迟操作。昨天突然想了解下setTimeout的handler到底在队列中的什么位置特别好奇。今天特地来测试下。
定义和用法
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
语法
setTimeout(code,millisec)
参数描述
code
必需。要调用的函数后要执行的 JavaScript 代码串。
millisec
必需。在执行代码前需等待的毫秒数。
提示和注释
提示:setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。
以上定义来源于w3school.com
JavaScirpt线程
先了解下浏览器,浏览器是多线程的。
JavaScript引擎线程
界面渲染线程
浏览器事件触发线程
Http请求线程
JS运行在浏览器中,是单线程的,每个window一个JS引擎线程。既然是单线程的,的在某个特定的时刻只有特定代码能被执够行,并阻塞其它的代码。(至于ajax的实现这里就不说了。)
原理
来了解下setTimeout的简单的原理:
setTimeout调用的时候,JavaScript引擎会启动定时器timer,大约millisec(ms)以后执行code,当定时器时间到,就把该事件放到主事件队列等待处理。
注意:
浏览器JavaScript线程空闲的时候才会真正执行
为什么呢?因为当JavaScript线程的正在出来其他JavaScript代码时,其实以已经阻塞了其他的代码,其中包括的setTimeout的定时器部分的实现。
代码测试
functiontestHandler() {
console.log("调用了setTimeout的函数");
}
window.οnlοad= function() {
console.log("开始");
console.log("设置setTimeout 100ms");
setTimeout(testHandler,100);
console.log("休眠1000ms");
sleep(1000);
testNext();
console.log("结束");
}functiontestNext() {
console.log("后续执行的函数");
}functionsleep(number) {varnow= newDate();varexitTime=now.getTime()+number;while(true) {
now= newDate();if(now.getTime()>exitTime)return;
}
}