定时器概念
js提供的一些用来延迟执行一段代码的方法,比如setTimeout, setInterval
1.setTimeout
概念
设置一个定时器,在时间到期后【执行一次】代码
语法
timeoutId = setTimeout(fn [, delay, param1, ...])
timeoutId = setTimeout(code[, delay])
ps:
timeoutId: 定时器ID
fn: 延迟函数
code: 延迟执行的代码,不推荐使用
delay: 延迟时间,单位:毫秒(ms), 默认值0
param1: 给延迟函数传递的参数
清除定时器
clearTimeout(timeoutId)
2.setInterval
概念
以固定的时间间隔,【重复执行】一段代码
语法
同setTimeout
清除定时器
clearInterval(intervalId)
3. setInterval 模拟 setTimeout
var timer = setInterval(function () {
console.log(1);
clearInterval(timer)
}, 1000);
var timeoutId= setTimeout(function(){
console.log(2);
}, 1000);
4.setTimeout模拟setInterval
function fn () {
setTimeout(function () {
console.log(1);
fn();
}, 1000);
}
fn();
ps: 跟setInterval区别
setTimeout模拟出来的,只有在回调函数结束后,才会去执行下一次定时器;
setInterval则不管回调函数的执行情况,时间到了,就在事件队列中插入一个执行的回调事件。
定时器工作原理
待补充。。。
测试例子
1.测试1
var flag = true;
setTimeout(function() {
flag = false;
}, 1000);
while(flag){}
console.log('end');
ps:
输出结果:陷入死循环
end不会输出;
1.js是单线程的;
2.定时器的回调会在正在执行的任务结束后才执行;
3.while循环直接陷入了死循环,一直占用进程,不给定时器回调函数执行的机会。
2.测试2
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i); // 10
}, 1000);
}
输出结果:10个10
1.当i=0的时候,生成一个定时器,将回调函数插入事件队列中,等待当前队列中无任务执行时立即执行;
2.for循环执行时,回调函数的执行被搁置,等待执行;
3.for循环结束,事件队列中有10个回调函数,依次执行;
4.for循环结束后,i=10,为全局变量,所以。。。
3.测试3
var person = {
name: 'lucy',
say: function(){
console.log(this.name);
},
wait: function(){
setTimeout(function(){
this.say();
}, 1000);
}
};
person.wait();
结果:Uncaught TypeError: this.say is not a function
1.setTimeout调用的代码运行在与所在函数完全分离的上下文环境下,this指向全局对象(window);
2.window对象下不存在wati方法,所以。。。
更正:
setTimeout(function(){
this.say();
}.bind(this), 1000);
或者
wait: function(){
var _this = this;
setTimeout(function(){
_this.say();
}, 1000);
}