setTimeout和setIntertval是js中的两个定时器。setTimeout是延迟执行,setInterval是定时执行。
详细介绍
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
语法:
/**
* @param code{Function} 必需,要调用执行的代码
* @param millisec{Number} 必需,在执行代码前需等待的毫秒数
*/
setTimeOut(code,millisec)
清除定时器:
var timer = setTimeout(code,millisec);
clearTimeout(timer) // 用于清除定时器,timer是该定时器的编号
setInterval()方法用于在指定的毫秒数间隔调用函数或计算表达式。
语法:
/**
* @param code{Function} 必需,要调用执行的代码
* @param millisec{Number} 必需,在执行代码前需等待的毫秒数
*/
setInterval(code,millisec)
清除定时器:
var timer = setInterval(code,millisec);
clearInterval(timer) // 用于清除定时器,timer是该定时器的编号
业务场景
setTimeout常用于延迟执行某些事务或方法,
setInterval是一般定时刷新业务,用于业务数据同步等。
同&异
同:都是异步操作的函数,接受两个参数,第一个是要执行的代码块,第二个是以毫秒为单位的时间间隔。
异:setTimeout只执行一次,setInterval重复执行。
定时器中的this指定
先看几个例子
例子1:使用匿名函数
var func = {
say: function(){
setTimeout(function(){
console.log(this);
},1000)
}
}
func.say(); // [window]
例子2:使用箭头函数
var func = {
say: function(){
setTimeout(()=>{
console.log(this);
},1000)
}
}
func.say(); //[say]
例子3:使用bind()函数
var func = {
say: function(){
setTimeout(function(){
console.log(this);
}.bind(this),1000)
}
}
func.say(); //[say]
定时器中的执行代码的本身的this永远指向window,因为本身定时器就是window的函数,由于定时器是异步执行的,所以当定时器中的代码执行的时候,运行时作用域是window。
解决定时器的this指向问题:
1.使用es6中的箭头函数。箭头函数可以让定时器中的执行代码this绑定定义时的作用域,而不是本身运行时所在的作用域。如例子2。
2.使用bind绑定作用域,如例子3,bind()函数中的this不属于定时器执行代码中的this,故指定的是say函数,所以使用bind()可以绑定定义时作用域。虽然apply和call也可以绑定作用域,但这两个函数会立即执行,失去定时效果。
定时器的进一步理解
-
定时器虽然说在指定毫秒数执行代码,但由于js引擎是单线程的,定时器只是指定在毫秒数后把执行代码放入事件执行队列中。如果队列不为空,定时器的实行代码就会被延迟。可以尝试一个无限循环事件和一个定时器。
-
毫秒数为0的情况
例子4:
setTimeout(function(){
console.log('0');
},0)
console.log('1');
// 1
// 0
这里的定时器时间虽然为0,但是一般规定定时器最小的时间间隔为4ms,为了防止定时器被无限调用而影响性能。
小声说话:百尺竿头更进一步。