JS线程
最近发现一个问题,setTimeout设置为0时,并不是瞬时0秒后触发里面的函数,从而牵引出关于js线程的一些问题。从多方资料了解了很多,现在做个总结加深自己的理解,也为一些不知道的朋友做个讲解,欢迎指正。
我们从js的线程讲起。
浏览器的内核是多线程的,他们相互配合保持同步。一个浏览器至少有三个常驻线程,JS引擎线程(用于处理JS事件),GUI渲染线程(用于页面渲染),事件触发线程(用于交互)。
几个要点:
-
JS引擎线程:是基于事件驱动的,采用单线程运行机制。即JS引擎会只会按顺序从JS队列中取任务并执行。所以无论什么时候都只有一个JS线程在运行JS程序
-
GUI渲染线程:与JS引擎线程是互斥的,在页面渲染时启用。所以头部加载JS文件与加载CSS文件会发生阻塞现象。
-
当一个事件被触发时该线程会把事件添加到JS队列的队尾,等待JS引擎的处理。如setTimeout、Ajax、鼠标点击事件等。
JS引擎分析:(网上图片)
事件会不断按顺序存入JS队列,由JS引擎按顺序执行。
要点:
1.JS引擎执行到setTimeout的时候,会启动一个计时器添加在该JS队列后面,等到执行到计时器时,再进行延迟操作,所以setTimeout为0时也不是即刻执行
2.JS引擎执行到Ajax时,浏览器会分发出一个线程专门处理回调,当产生状态变更时,事件会加入JS队列等待处理。这就是所谓的异步
其实JS队列也不是一定按顺序执行,不同浏览器会有不同的事件循环来轮询JS队列,找出更优先的事件,当然,这部分内容属于高深内容,等我升级了再学,现在只要记住按顺序就行了
一次事件改变页面的JS线程简单示意图: