前端学习/踩坑系列2:setTimeout和setInterval的理解

1,307 阅读3分钟

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,为了防止定时器被无限调用而影响性能。


小声说话:百尺竿头更进一步。