进程&线程
-
进程就是一个执行程序,比如浏览器中打开了一个页面就是开启了一个进程。
-
线程是进程中具体做事情的,比如说打来页面后要做的事情。
同步&异步
-
同步就是同一时间内只能执行一行代码,只有当前代码执行完毕之后,才会执行后面的代码。
-
异步就是同一时间内可以执行多件事情。而JS中的异步编程并不是同一时间内执行多行代码,而是基于EventLoop事件循环和浏览器的多线程机制实现的事件监听、排队的机制。
浏览器是多线程的
-
GUI渲染线程
-
JS引擎线程 【用来执行JS代码的,也称为主线程】
-
异步http请求线程 【ajax、fetch、jsonp】
-
webworker、 websocket
-
定时器触发线程
-
监听事件触发线程
......
异步任务
- 异步微任务 【优先级高】
-
promise「resolve/reject/then...」
-
async await
-
requestAnimationFrame 实现JS动画
-
queueMicrotask 创建一个新的异步微任务
-
IntersectionObserver 监听DOM元素和视口交叉的信息
-
MutationObserver 监听DOM元素属性改变
-
process.nextTick 【Node中的】
-
...
- 异步宏任务 【优先级低】
-
定时器 setTimeout/setInterval
-
DOM事件绑定
-
HTTP异步数据请求(ajax、fetch、jsonp...)
-
MesageChannel
-
setImmediate 【Node中的】
-
...
EventLoop事件循环机制
-
浏览器打开页面之后,除了开辟堆栈内存之外,还开辟了WebAPI任务队列和EventQueue事件队列
-
JS引擎线程【主线程】从上到下执行栈中的代码,遇到异步任务会先放到WebAPI任务队列中。然后浏览器分配相应的线程监听其是否可以执行,可以执行的话在将其挪移到EventQueue事件队列中等待执行。
-
执行栈中的同步任务执行完毕之后,浏览器会每隔5-7ms到EventQueue事件队列查看是否有可执行的异步任务。有的话就按照进入EventQueue事件队列中的先后顺序将其转移到执行栈中等待执行,执行完毕之后,会再次向EventQueue事件队列中取出异步任务到执行栈中。依次往复,直到EventQueue事件队列中的异步任务执行完毕。
-
EventQueue事件队列中分为异步微任务队列和异步宏任务队列
-
异步微任务放到异步微任务队列中,异步宏任务放到异步宏任务队列中
-
异步微任务的优先级高于异步宏任务,不论异步宏任务是否比异步微任务来的早
-
等到异步微任务执行完毕之后,在执行异步宏任务。同一任务类型的,则按照进入队列的先后顺序执行。