前言:
🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈
🏠 个人主页: Morning的主页
📕系列专栏:前端面试备战
📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏
目录
1.进程与线程
面试题:进程与线程的区别?JS单线程带来的好处?
-
进程与线程都是CPU工作时间片的一个描述。进程是CPU在运行指令及加载保存上下文所需的时间。线程是进程中的更小单位,描述了执行一段指令所需要的时间。(可以理解为在一个浏览器中打开了一个Tab页就是创建了一个进程,其包括多个线程:渲染线程、js引擎线程、HTTP请求线程等等)
-
上文提到了渲染线程和JS引擎线程(为互斥线程)。在JS运行时可能会阻止UI渲染,因为JS可以修改DOM,如果JS执行的时候UI线程还在工作,就可能导致不能安全的渲染UI。这就是单线程的一个好处,得益于JS是单线程运行的,可以达到节省内存,节约上下文切换时间,没有锁的问题的好处
2.执行栈
面试题:什么是执行栈
可以把执行栈认为是一个存储函数调用的栈结构,遵循后进先出原则 (后执行的函数先弹出栈)
function fn2(){
throw new Error('error')
}
function fn1(){
fn2()
}
fn1()
从该报错中可看出,fn2先执行完,fn1再执行完(也是执行栈中的弹出顺序)
3.浏览器中的Event Loop
<1>Event Loop开始的时候,会从全局一行一行执行,遇到函数调用,会压入到执行栈中,被压入的函数被称为帧,函数返回后从执行栈中弹出
function fn2(){
console.log(2);
}
function fn1(){
console.log(3);
fn2()
console.log(4);
}
fn1()
fn1进入执行栈,输出3 ---> fn2进入执行栈,输出2,弹出执行栈 ---> 输出4,fn1弹出执行栈
<2>.JS中的异步代码,如fetch、setTimeout、setInterval压入到调用栈中的时候里面的消息会进到消息队列。消息队列中的消息会等到调用栈清空之后再去执行
function fn2(){
console.log(2);
}
function fn1(){
setInterval(()=>{
console.log(3);
},1000)
fn2()
console.log(4);
}
fn1()
fn1进入执行栈 ---> setInterval执行(3进入消息队列) setInterval弹出执行栈 ---> fn2进入执行栈,输出2,弹出执行栈 ---> 输出4,fn1弹出执行栈 ---> 执行栈清空,输出消息队列中的3
<3>.promise、async、await的异步操作会马上加入到微任务中去,会在调用栈清空的时候立即执行。调用栈中的微任务会立马执行
var p=new Promise(resolve=>{
console.log(4);
resolve(5)
})
function fn1(){
console.log(1);
}
function fn2(){
setInterval(()=>{
console.log('2计时器');
},1000)
fn1()
console.log(3);
p.then(resolve=>{
console.log(resolve);
})
}
fn2()
new Promise进入执行栈,立即执行,输出4(5进入微任务队列)---> fn2进入执行栈 ---> setInterval执行,(‘2计时器’进入消息队列), setInterval弹出执行栈 ---> fn1进入执行栈,输出1 ---> 输出3 ---> 执行栈清空,立即执行微任务队列,输出5 ---> 输出消息队列中的‘2计时器’
疑问:在此篇中我还是有着很多问题,消息队列、微任务队列与宏任务、微任务有什么联系。
什么会进入消息队列,什么进入微任务队列?
希望小伙伴的探讨、指正、答疑
2024.1.25更新 对eventloop又有了新的见解
eventloop,事件循环机制。
事件循环机制的前提是我们要知道js代码是单线程的,为了防止代码阻塞,将代码分为了同步任务和异步任务。同步任务由JS引擎执行,异步任务由宿主环境(浏览器、Node)执行。
同步代码放入执行栈中,异步代码等待时机成熟送入任务队列排队。
在执行栈执行完毕后,会检查任务队列中是否有异步任务,有的话就送到执行栈中执行。再检查,执行,循环往复,这便是事件循环的意义。
在ES6中引入了Promise,此时不需要浏览器JavaScript引擎自身也可以发起异步任务了
因此JS将异步任务又分为了宏任务(事件,网络请求如Ajax,Fetch,定时器)和微任务(Promise,promise本身是同步的,但是catch和then的回调函数是异步的)