一、进程和线程
进程:cpu资源分配的最小单位,孤立执行的一个单元,类似打开一个窗口,或者播放一首歌。
线程:cpu调度的最小单位,为了执行进程的任务,线程是相互合作的,多个线程是共享资源的。
-在浏览器中,新开一个tab页是进程还是线程?
-进程
-每个tab是不同的进程,窗口之间如何做通信?
-浏览器存储:storage、cookie => 多种存储的区别
二、浏览器原理
一个浏览器是有多个线程的,包括GUI渲染引擎、JS引擎、定时器触发引擎、异步HTTP请求线程、事件触发线程
1、GUI引擎
解析HTML/CSS、构建DOM树 => 布局 => 绘制
*GUI引擎和JS引擎是互斥的,当直接Js引擎时候,GUI会挂起,当任务队列空闲时,才会继续执行GUI线程*
2.Js引擎
处理JS/解析执行脚本;分配、处理、执行待执行的时间、event队列;阻塞GUI渲染
***作为事件的执行者,接受所有的请求
3.定时器触发引擎
异步定时器的处理与执行- setTimeOut & setInterval
来接受js引擎分配的定时器任务,并进行计数
处理完成之后交于事情触发完成线程触发
4.异步HTTP请求线程(通信I/O线程)
用来异步执行请求类的处理:Promise/ajax
接受js引擎分配的HTTP请求
5.事件触发线程
可以接受定时器、异步、用户操作
**将回调过来的时间依次接入到··任务队列··的队尾,还给JS引擎
三、JS执行原理
执行我们的逻辑时候,分为两种 :
1.Memory Heap:储存堆,用来分配内存,需要存储的东西全部放进去
2.Call Stack :执行栈,执行回调,每一个执行的东西都放进去
四、EVENT-LOOP
1.执行栈
*栈的特点:先进后出
*Js单线程语言,单步执行
*每执行一行代码,就会按照顺序放在执行栈中,先读到谁,就先放进去
*.webAPI:DOM/AJAX/setTimeOut 通过事件触发引擎直接跟我们的执行栈进行一个交互
-JS堆栈的执行顺序和堆栈溢出 => 性能优化
function run(){
func1()
}
function func1(){
func2()
}
function func2(){
console.log("this is func2")
}
run()
2.任务队列
从两个方面:
宏任务(macro) or 微任务(micro)
宏任务:script代码段、setTimeOut、setInterval、I/O
微任务:new Promise().then()
有微则微 ,无微则宏
同步 or 异步
如果是同步会直接进入主线程(执行栈),如果是异步的会进入event table(对异步任务进行一个生命和收集),将们放入
event queue(事件队列)。
-执行顺序
setTimeOut(() => { --> 异步 宏任务
console.log("time out")
})
Promise.resolve(1).then(() => { --> 微任务
console.log("Promise")
})
console.log('hi') -->同步任务 宏任务
//打印结果:hi promise timeOut
解释:先执行同步任务,console.log("hi")直接放到了执行栈中,timeout作为异步放到了事件队列event queue,
promise作为微任务,等待主线程中的宏任务完成之后,进行promise微任务,然后取事件队列timeout放入执行栈中执行
执行一个宏任务(栈中没有就从事件队列中获取),执行过程中遇见微任务就把它加入微任务队列中,宏任务执行完毕,立即执行
微任务队列中的所有微任务(依次执行),当前宏任务执行完毕,开始检查渲染,进行GUI线程渲染,渲染完毕后,JS线程继续接管,
开始执行宏任务(从evevt queue中获取)
持续学习补充中···········