const setTimeoutVal = setTimeout(() => { console.log('setTimeout'); }, 1000)
console.log('setTimeoutVal', setTimeoutVal);
clearTimeout(setTimeoutVal)

一.对于 setTimeout函数来说,

它是JavaScript中常见的一个API。
它接收两个参数:一个是要执行的函数和一个延迟时间(以毫秒为单位)。
前面这个参数我们可以传匿名函数:

 setTimeout(function() { console.log('setTimeout'); }, 1000)

或者 显式函数

 setTimeout(function timeout() { console.log('setTimeout'); }, 1000)

或者 上面例子中的箭头函数

在上面这个例子来说意思就是在1000ms之后我们执行setTimeout函数中的回调函数。
这里需要注意,setTimeout函数中的回调函数会在事件循环的下一个循环中执行。
也就是说,在setTimeout函数执行完毕之后,会先将回调函数放入事件循环的队列中,然后继续执行其他任务,直到事件循环的下一个循环中,才会执行回调函数。

setTimeout在JavaScript中属于宏任务
常见的宏任务包括:setTimeout、setInterval、requestAnimationFrame等。

const setIntervalVal = setInterval(() => { console.log('setInterval'); }, 1000)
console.log('setIntervalVal', setIntervalVal);
clearInterval(setIntervalVal)

二.对于setInterval函数来说,

它和setTimeout函数类似,也是接收两个参数:一个是要执行的函数和一个延迟时间(以毫秒为单位)。
前面这个参数我们可以传入的函数也是跟setTimeout函数相同
在上面这个例子来说,意思是在1000ms之后我们执行setInterval函数中的回调函数。
这里需要注意,setInterval函数中的回调函数会每隔指定的延迟时间执行一次。这个跟setTimeout函数不同,setTimeout函数中的回调函数只会执行一次。

setTimeout函数表示的是在指定的延迟时间之后执行一次回调函数,setInterval函数表示的是每隔指定的延迟时间执行一次回调函数。
所以这就决定了它们适用的业务场景不同。

我们在需要反复刷新的业务逻辑中,一般会使用setInterval函数
而setTimeout函数则试用在延迟某些事务或者方法
setInterval在JavaScript中也属于宏任务

三.我们调用这两个函数的时候,它们都是有返回值的。

这两个返回值都是数字类型的,表示的是一个ID,我们可以通过这个ID来取消对应的定时器。
取消定时器的方式是通过clearTimeout和clearInterval这两个函数。
这两个函数的参数就是前面提到的返回值。

四.在谈到它们的this指向时

需要注意,这两个函数的this指向都是window。
关于this的玩法,到时候我出一篇专门玩this的博客

五.我还想玩一下这两个函数如果后面的参数赋值为0或者负数是什么情况呢?

我发现我把timeout这个参数赋值为负数的话,还是可以打印,并没有报错。
后面我发现其实负数或者赋值为0的话,其实是一样的,
因为setTimeout函数的第二个参数是一个延迟时间,如果这个延迟时间小于0的话,其实它还是会被认为是0。
在它为0时表示希望立即执行,但是它还是会在事件循环的下一个循环中执行。

后面思考了一下其实这么做也有道理的,如果我们如果让它一直调用的话,
其实它就会一直占用着事件循环的资源,这样就会导致其他任务无法执行。
所以为了避免这种情况的发生,让它在事件循环的下一个循环中执行,这样就不会一直占用资源了。

查阅了资料后,发现一般规定定时器最小的时间间隔为4ms。
但是我发现如果setInterval第二个参数设置为0或负数的时候,它就会一直执行下去,
直到我们手动取消它。

setTimeout(() => { console.log('setTimeout'); }, -1)
setInterval(() => { console.log('setInterval'); }, 0)

负数我们玩过了,我们来试一下嵌套呢?
setInterval的嵌套,在开发过程中暂时没遇到
不过我们来玩一下setTimeout的嵌套,

setTimeout(() => {
  console.log('(3层)第一层setTimeout');
  setTimeout(() => {
    console.log('(3层)第二层setTimeout');
    setTimeout(() => {
      console.log('(3层)第三层setTimeout');
    }, 1000);
  }, 1000);
}, 1000);

setTimeout(() => {
  console.log('(2层)第一层setTimeout');
  setTimeout(() => {
    console.log('(2层)第二层setTimeout');
  }, 1000);
}, 1000);

最后这个打印结果就让大家自己去玩。


肉夹馍
4 声望2 粉丝

努力学习,想要做全栈工程师的前端从事人员😁