setTimeout知多少

832 阅读2分钟

背景:

setTimeout是日常开发中常用的一个webApi,熟悉其原理能够帮助你更好的开发业务代码,减少日常开发的填坑时间。


抛出问题:

1.在使用setTimeout的时候,有很多因素会导致回调的执行时间比预设的时间要长。比如下面这段代码:

function con() {	console.log(11);}setTimeout(con, 0);for (let i = 0; i < 6000; i++) {	console.log(1)}

既然设置了只延迟为0ms后执行,为什么还是在for函数执行完之后再执行呢? 异步啊!当然得在同步的代码执行完后再执行setTimeout。为什么是异步的呢?异步机制是如何实现的?


解析:

要想理清楚setTimeout的原理。就不得不说js执行任务的消息队列。在JS主线程执行代码的过程中,如果有任务则会从尾部进入,取任务从头部取出,主线程会不断的从消息队列取任务,直到消息队列的任务为空。

但是setTimeout是另外一个任务队列,为延迟队列,所有需要延迟执行的任务都会放到这个任务队列中。

delayed_incoming_queue.push(timerTask);

在执行完一个消息队列里的任务后,会有一个函数---ProcessDelayTask 函数,该函数是专门用来处理延迟执行任务的。ProcessDelayTask 函数会根据发起时间和延迟时间计算出到期的任务,然后依次执行这些到期的任务。等到期的任务执行完成之后,再继续下一个循环过程。


  1. 如果有嵌套使用setTimeout的话,那么系统会把间隔时间设置成4ms。


如果setTimeout被嵌套多层,会被延迟执行,所以如果是实时性高的业务就不要用setTimeout了。比如动画就不建议用setTimeout了。


3.setTimeout有最大的延迟执行时间。

function con(){  console.log(111)}setTimeout(con,2147483648);

当延迟时间被设置成最大值,则会被立刻调用。原因是: Chrome、Safari、Firefox 都是以 32 个 bit 来存储延时值的,32bit 最大只能存放的数字是 2147483647 毫秒.


4.setTimeout的this指向不稳定问题。

这个就不说了,可以通过bind与箭头函数来指定this。



总结:js里随便一个小东西都能扯出好多,学无止境。通过对setTimeout的学习,让我对js的执行原理理解更加深入了,也发现react里的实现原理,感觉与js底层执行原理有一些类似,突然就觉得现在的框架啥都能与js底层执行原理扯的上关系,非常有意义的学习


文章转自: setTimeout知多少