首先要纠正一个误区:JS其实就是一门语言,说是单线程还是多线程得结合具体运行环境(浏览器)。
浏览器的内核是多线程的。
一个浏览器通常由以下几个常驻的线程:
渲染引擎线程:顾名思义,该线程负责页面的渲染
JS引擎线程:负责JS的解析和执行
定时触发器线程:处理定时事件,比如setTimeout, setInterval
事件触发线程:处理DOM事件
异步http请求线程:处理http请求
JS引擎
负责JS代码的解析和执行(注意是浏览器自己开了一个线程)。通常包括以下几个步骤:
词法分析:将源代码分解为有意义的分词
语法分析:用语法分析器将分词解析成语法树
代码生成:生成可执行代码(将所有JS代码全部生成为可执行代码)
函数调用栈的更新:遵循代码顺序,不同上下文出入函数调用栈。伴随函数调用栈的更新,JS代码逐句执行至尾部。
浏览器在运行时只开启了一个JS引擎线程来解析和执行JS。且要记得无论是同步还是异步执行,JS引擎线程的运行始终是非阻塞的,这是在设计之初就定下的。
JS异步执行
JS引擎的事件循环机制是JS实现异步执行的前提。在上下文的不断切换,函数调用栈的更新过程中,一旦发现"事件绑定,AJAX,setTimeout/setInterval"等任务,会把它们会将其放入消息队列中。当函数调用栈为空时,JS引擎会执行一次循环,将事件队列的队首出队至函数调用栈中。
待续