js中的线程与进程

105 阅读3分钟

进程是拥有资源的最小单位,线程是独立调度的最小单位。线程间可以共享进程的公共数据、全局代码、文件,但不能共享线程独有的资源,比如线程的栈指针这种标识数据。

1、浏览器的多进程

浏览器本身是多进程的,每打开一个新的tab页,就会创建一个独立的浏览器进程。

浏览器的进程包括主进程(负责协调主控)、第三方插件进程、渲染进程等。

其中渲染进程会有多个线程,比如

GUI渲染线程:页面渲染绘制

JS引擎线程:负责js代码的执行,这就是js执行的单线程(GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,保存在一个队列中等到JS引擎线程执行完后再执行。所以如果JS执行的时间过长,就会导致页面渲染被阻塞)

事件触发线程:包括页面内事件(onclick、onscroll)和网络事件(onload、onerror)

定时器触发线程:settimeout、setinterval

异步http请求线程

2、js引擎线程的执行

js是单线程语言,这里的单线程指的是只有一个主线程(JS引擎线程)负责代码的执行。

主线程在看到代码时,如果是同步代码,就会按顺序执行;

如果是异步代码,就会放入任务队列中。

异步代码分为3种,事件触发、定时器、异步请求。当主线程执行到相应代码时,会把它们交给对应的线程。

事件触发线程,事件被触发后将代码放进任务队列;

定时器触发线程,计时,在设定时间结束后将代码放进任务队列;

异步http请求线程,监控请求状态,状态改变后将回调函数放进任务队列

(都不是立刻执行,只是添加进任务队列)

主线程执行完全部同步代码后,会依次从任务队列中提取任务执行。

所以js中的异步代码,执行时间并不是完全准确的,如事件触发的异步代码,并不是事件触发就立刻执行,要等到主线程从任务队列中提取到后才会执行,定时器同理。

3、宏任务和微任务

js主线程会先执行同步代码再执行任务队列中的异步代码,异步任务队列也分为两条:微任务队列和宏任务队列。

上面说到的放到其她线程中的任务都属于宏任务队列。(宏任务是由宿主环境发起的(浏览器、node),微任务是由js引擎自身发起的)

不同的任务会被放到不同队列中,js主线程会先执行微任务队列中的任务,再执行宏任务队列中的任务。

微任务队列:

promise(promise本身是同步的,then/catch是异步的)

async/await

object.observe