0%

手写setTimeout和setInterval

setTimeout

写代码之前需要知道setTimeout实现原理:本质上就是在给定的时间向任务队列添加回调函数,并执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function mySetTimeout(...rest){
// 1.得到调用setTimeoutMy函数时的时间戳
let start =new Date().getTime();
// 2.得到回调函数结束的时间
let end = start+ rest[1];
// 3. 监听事件变化,当事件到达指定的结束时间时,结束回调函数
let timer =setInterval(()=>{
let time =new Date().getTime();
if(time>=end){
clearInterval(timer);
rest[0](rest[2]);
}
},17)
console.log('同步执行----');
}

mySetTimeout((res)=>{
console.log(res);
},1000,'执行结果')
------------

结果:
同步执行---- # 从这里可以看出setTimeout本身执行是同步的,执行的回调函数是异步的
执行结果 # 输出结果,是在1秒之后输出

setInterval

写代码之前需要知道setInterval实现原理:本质上就是每隔一定的时间向任务队列添加回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function mySetInterval(...rest) {
/**
* rest数组接受三个参数:
* 1)回调函数 rest[0]
* 2)执行回调函数所需的时间 rest[1]
* 3)操作元素 rest[2]
*/

function interval() {
if (rest[2] > 0) {
// 2:利用setTimeout在给定的时间,就调用回调函数的原理,使用递归思想,自己调用自己.
setTimeout(interval, rest[1])
rest[0]();
rest[2]--;
}else{
// 3:条件不符合,退出函数
return
}
}
// 1:利用setTimeout在mySetInterval被调用时异步调用一次。
setTimeout(interval, rest[1]);
console.log('同步执行----');
}
mySetInterval(() => {
console.log(1)
}, 1000, 8)

-----------
结果:
同步执行---- # 从这里可以看出setIterval本身执行是同步的,执行的回调函数是异步的
1
1
1
1
1
1
1
1 # 输出81

结论:

setTimeout:

1.得到调用setTimeoutMy函数时的时间戳;

2.得到回调函数结束的时间;

3.监听事件变化,当事件到达指定的结束时间时,结束回调函数。

setIterval:

1:利用setTimeout在mySetInterval被调用时异步调用一次;

2:利用setTimeout在给定的时间,就调用回调函数的原理,使用递归思想,自己调用自己。

注意:

setTimeoutsetIterval本身执行是同步的,执行的回调函数是异步的。