什么是进程?
进程是系统分配资源和调度的最小单位,多个进程之间是相互独立的 不会互相影响的,因此一个进程挂掉也不会影响其他进程
浏览器就是采用多线程模型,一个页面挂掉了也不会影响整个浏览器
每个网页都在隔离在自己的运行环境中,因此不同页面之间的代码是不能进行交互的
浏览器的进程组成
-
- 浏览器的主线程 (管理浏览器的整体页面)
- 渲染线程(每个页面一个,负责渲染页面的内容以及响应用户交互)
- 网络线程 (加载资源的进程)
- 插件线程(独立运行的)
- GPU绘图线程(使用GPU进行加速图形渲染)
- 事件触发线程 (事件环,调度任务)
就如同女娲捏人一样,先捏长条(主线程),然后画出四肢(渲染线程),在安个脑子(网络线程),再捏几个武器放一边(插件线程),再装点指令会吃会睡(事件触发线程),让脑子更聪明点(GPU渲染进程)
同步和异步的区别
同步和异步的区别在于是否需要等待这个操作的返回结果,需要等待的是同步, 不需要等待的是异步
异步任务划分
异步任务分为了 宏任务和微任务
宏任务(可以理解为浏览器自带的)
- 定时器
- setImmediate
- 脚本执行,
- ui渲染,
- http请求,
- MessageChannel,(消息通道)
微任务(可以理解为环境自带的)
- Promise.then (处理异步逻辑)
- Generator 函数
- async/await
- process.nextTick (node的异步)
- ququeMicotask (微任务队列)
- mutationObserver (h5提供的api)
- requestAnimationFrame(动画,帧执行之前)
- requestIDlecallback(动画,帧执行完毕后剩余的时间)
代码执行过程
- 先执行脚本解析,代码自上而下加载,遇到同步代码立即执行,遇到宏任务待它成功以后放入到宏任务队列中,遇到微任务则立即放入到微任务队列中
- 微任务执行完毕后,要检测"是否需要"渲染,浏览器有自己的刷新频率。 渲染一定是在宏任务之前做的。
- 宏任务执行的时候会产生一个微任务队列,
- 当宏任务执行完毕以后,会立即清空微任务队列,(清空的过程可能会产生 宏任务、微任务,产生的宏任务逻辑和上面一致,产生的微任务会被放到当前队列中)
- 微任务清空完毕以后,再取一个宏任务执行
宏任务和微任务的调度操作靠的就是eventLoop来实现的
举个栗子
console.log(1);
async function fnOne() {
console.log(2);
await fnTwo(); // 右结合先执行右侧的代码, 然后等待
console.log(3);
}
async function fnTwo() {
console.log(4);
}
fnOne();
setTimeout(() => {
console.log(5);
}, 2000);
let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码
console.log(6);
resolve();
console.log(7);
})
setTimeout(() => {
console.log(8)
}, 0)
p.then(() => {
console.log(9);
})
console.log(10);
console.log(11);
setTimeout(() => {
console.log(12);
let p = new Promise((resolve) => {
resolve(13);
})
p.then(res => {
console.log(res);
})
console.log(15);
}, 0)
console.log(14);