前端面试之浏览器运行机制EventLoop(六)

15 篇文章 0 订阅

最近在准备面试,感觉好些东西了解,但是了解的深度有限。自己就总结了几个模块,打算强化一下。如果你感觉我的文章对你有帮助,请点赞。如果感觉有哪些不足之处,可以留言。让我们一同进步,学习!!!
最后在说明一下,这个系列我会一直写下去。如果,你有什么好的方向,也可以提出来。

进程与线程

进程

我们常常说JS是单线程的,有没有想过为什么呢?我们学习操作系统的时候说的进程与其又是什么关系呢?虽然面试官不会直接问我们这一点。但是如果我们能在谈这个问题的时候,讲出来,说清楚,效果怎么样,拭目以待…

按照书上的说法,进程CPU分配资源的最小单位。我们每打开一个软件,计算机就会给其分配进程,同时就会为其分配各种资源。所以,电脑打开的软件多了,会卡,就是这个原因。而为了管理这么多进程,计算机就引入了时间片转轮调度算法(我个人已经忘记咋回事了,回头复习一番,写篇文章)。
别的浏览器不清楚(如果是,请告知),Chrome浏览器,每开一个页面,就会开一个进程。所以开的越多,电脑越卡。

线程

同理于CPU管理进程,线程进程管理的最小单位。而线程受进程管理,而开进程就是为了使用软件,所以说,一个软件程序,可以同时运行多个线程,执行不同的任务。

为什么JS是单线程语言

先解释,什么叫做单线程。单线程指,在一定时间内,浏览器只能做一件事。看到这,我估计大家也明白了。JS是运行在浏览器中的语言,而我们用户会与浏览器有有交互,操作DOM。如果一个线程添加DOM,一个线程删除DOM,这不就是自相矛盾么。

既然JS是单线程,那又为什么引入Web Worker

首先说明一下Web Worker 是HTML5 引入的,就是为了JS提供一个多线程的环境(有需要就留言,我花时间写一篇)。但是这个多线程却与我们所说的JS单线程不矛盾,第一Worder 受主线程管理,当执行完操作之后,会将执行结果返回主线程。另一个主要的是 worker不可以操作DOM。

事件循环(Event Loop)

我们一直讲时间循环,这一次我们要知道什么是时间循环
在JS中,我们很自然的将任务分为同步任务和异步任务(Ajax请求,setTimeout 和 setInterval,Promise 等)

浏览器运行方式:先执行同步任务(运行栈,也叫执行栈),遇到异步任务就挂起来管理。而当我们的同步任务运行栈执行完毕后,就要从异步任务中选取,加入到执行栈中执行。
这个时候,那些异步任务先加进来,哪些任务后加进来的过程。就叫事件循环(Event Loop)

let setTimeoutCallBack = function() {
  console.log('我是定时器回调');
};
let httpCallback = function() {
  console.log('我是http请求回调');
}
// 同步任务
console.log('我是同步任务1');
// 异步定时任务
setTimeout(setTimeoutCallBack,1000);
// 异步http请求任务
ajax.get('/info',httpCallback);
// 同步任务
console.log('我是同步任务2');

注:该例子引用于掘金 isboyjc 作者。接下来,对于这个的解释,也引用了部分该文的思想。

上诉代码执行:

JS从上到下开始执行,
1、执行同步任务1
2、执行到异步的定时任务。会将其交给定时器线程定时器线程拿到该任务后会在一秒之后,将运行结果交给 事件触发线程,同时将其加入到自己管理的事件队列中
3、执行请求。同时会触发 http请求线程,http请求成功之后,会将其交给事件触发线程,事件触发线程同时也会管理他,将其加入到队列中。
4、执行同步任务

到了这个,我感觉就很清爽了,感觉就像我们前端写代码,分模块一样。各司其职。
定时器线程http请求线程
最终都会到达 事件触发线程管理这个队列
而我们的事件触发线程又将作为代表管理所有异步任务的先后顺序,送到 JS引擎线程执行

虽然我们有了各种线程来协助 事件触发线程。但是对于嵌套复杂的各种事件,我们就需要定一套规则来管理先后顺序。这就是宏任务以及微任务
接下来,就讲讲在其他博文中常见的 宏任务以及微任务

宏任务&微任务

需要注意的是宏任务和微任务不在一个任务队列,是两个队列

宏任务

常见宏任务
主代码块
setTimeout
setInterval
还有两个我不清楚的(必须承认)
setImmediate ()-Node
requestAnimationFrame ()-浏览器

微任务

常见微任务
Promise.then()
catch
inally
Object.observe

宏任务&微任务&GUI执行关系

宏任务 -> 微任务 ->GUI渲染 -> 宏任务

宏任务&微任务执行方式

浏览器会先执行宏任务,紧接着执行当前执行栈产生的微任务。接着就进行GUI渲染。渲染完成后,继续执行下一个宏任务。

主线程(JS引擎线程)从循环队列中取出任务执行,执行过程中,如果遇到宏任务,则将其放在队列的最后。等待下一轮的宏任务执行。
如果遇到微任务,则将其放在微任务队列中,在这一次宏任务结束,GUI渲染之前。执行该微任务队列。

需要说明的,第一次执行script是最大的宏任务。所以说,在执行完同步任务任务之后,会先执行微任务。就是这个原因。

浏览器是多线程的

渲染进程下的主要线程
GUI渲染线程
JS 引擎线程:这就是传说中的JS内核 等待任务队列中任务来,进行处理
// 两者互斥
事件触发线程
定时器线程(setInterval,setTimeout)
http请求线程

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值