我们知道 Javascript引擎是单线程的,而setTimeout方法的作用是延后执行目标代码,同时还可以继续往下执行
setTimeout是如何实现的?
这涉及到了浏览器内核的事件循环模型,在Javascript引擎之外,有一个任务队列,当执行到setTimeout时,延时方法会交给内核其他模块处理(与执行引擎主线程独立),当延时方法到达触发条件,这一延时方法被添加至任务队列里,执行引擎在主线程方法执行完毕后,会从任务队列中顺序获取任务来执行,这一过程是一个不断循环的过程,称为事件循环模型
下面通过一段示例代码,看一下整个执行过程
console.log('1');
setTimeout(function test(){
console.log('2');
},5000);
console.log('3');
执行过程
(1)log('1')入栈执行
(2)setTimeout test入栈执行 交由webapis处理
(3)log('3')入栈执行
(4)在setTimeout方法执行5秒后,timer模块检测到延时处理方法到达触发条件,于是将延时处理方法加入任务队列
(5)执行引擎的执行栈为空后,引擎开始轮询检查任务队列是否有任务需要被执行,就检查到延时方法test,于是将延时方法加入执行栈,test方法调用了log()方法,于是又将log(2)方法入栈执行,输出2,之后清空执行栈