为何要弄清楚线程和任务(宏、微)。咱们常常会被问到一个问题,就是当settimeout和http请求回调还有promise的执行顺序。这里就涉及到了这些知识点。以及为何js过大影响dom渲染。html
本文适合有必定经验的前端人员,对js运行机制有必定了解。前端
首先咱们要知道浏览器在渲染一个页面的过程种涉及到哪些工做原理。浏览器是多进程工做原理,什么是进程请自行学习(进程是内存分配的最小单位),一个进程又能够有多个线程(线程是执行的最小单位)。每打开一个tab标签就是新启一个进程(内存是独立的)。node
知道了浏览器进程,那么说一下一个进程的渲染过程:web
注意:这些都是属于浏览器的与js引擎单线程同样是属于浏览器的segmentfault
GUI渲染线程与JS引擎线程是互斥的。因此会JS若是执行时间过长就会阻塞页面。promise
那么咱们就能够理解了,咱们常常遇到的问题,就是当js执行的时候遇到时间定时器、异步加载等,他们的输出结果会在页面全部js执行以后执行的问题了,就是当遇到到时间定时器、异步加载等浏览器的事件触发线程就会触发他会产生一个任务添加到js的任务对列内,同理异步http请求线程、事件触发线程也是同样的。浏览器
由进程产生的非js引擎的任务会分红宏、微两种任务对列。bash
宏任务包括有:setTimeOut、setInterval、setImmediate、I/O、用户交互操做,UI渲染网络
微任务包括有:Promise(重点)、process.nextTick(nodejs)、Object.observe(不推荐使用)多线程
运行顺序是当js单线程执行完成以后就会去执行任务对列的内容。当有宏微都有的时候执行是,先执行宏观任务对列内的第一个任务,在执行所有的微观任务,在执行宏观任务对列内的第一个任务,在去执行所有微观任务。因此下面的代码输出结果是这个样子的:
console.log(1)
setTimeout(function() {
//settimeout1
console.log(2)
}, 0);
const intervalId = setInterval(function() {
//setinterval1
console.log(3)
}, 0)
setTimeout(function() {
//settimeout2
console.log(10)
new Promise(function(resolve) {
//promise1
console.log(11)
resolve()
})
.then(function() {
console.log(12)
})
.then(function() {
console.log(13)
clearInterval(intervalId)
})
}, 0);
//promise2
Promise.resolve()
.then(function() {
console.log(7)
})
.then(function() {
console.log(8)
})
console.log(9)
复制代码
结果: 1,9,7,8,2,3,10,11,12,13
这里注意: promise2执行,它的两个then函数加入宏队列
Web Worker 的做用,就是为 JavaScript 创造多线程环境,容许主线程建立 Worker 线程,将一些任务分配给后者运行。具体怎么使用请自行学习。
Web Worker 有如下几个使用注意点:
本文是是本身学习笔记,若有看不懂的可参考如下连接。
参考文章连接以下:
一、浏览器以及js运行原理:segmentfault.com/a/119000001…
二、宏观任务和微观任务原理:juejin.im/post/5da742…
三、Web Worker使用:www.ruanyifeng.com/blog/2018/0…