千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > 剖析JavaScript的单线程

剖析JavaScript的单线程

来源:千锋教育
发布人:wjy
时间: 2022-06-02 11:51:00 1654141860

**一、 浏览器的进程和线程**

浏览器的架构是多进程的,不同的浏览器采用不同的进程架构,这个没有统一的标准,以谷歌浏览器为例,他主要有四个进程,分别是顶层的Browser process,负责标签页网页呈现的Renderer Process,负责控制网页插件的Plugin Process和负责处理GPU的GPU Process。

剖析JavaScript的单线程

每个进程都可以通过创建线程或者调用线程来完成任务。打个比方,进程就相当于一个 公司,线程就相当于公司的一个部门,一个公司可以只有一个部门也可以有多个部分,公司内部的资源是共享的。

1

**二、浏览器的渲染进程**

我们前端主要和Renderer Process打交道,在这个进程里面主要包含五个线程:

2

1、GUI渲染线程,用于解析html、css,构建DOM树和RenderObject树,布局和绘制等浏览器界面渲染任务|不能和JS引擎线程同时执行。

2、js引擎线程,也就是我们常说的js内核,用于解析、运行javascript代码,不能和GUI渲染线程同时执行。

3、事件触发线程,用于监听和触发事件,可以理解成由js引擎线程来执行事件绑定代码,然后另开事件触发线程用来监听事件的触发,触发以后把事件处理函数里面的代码交给js引擎线程来执行,但是js是单线程的,事件处理函数里面的代码会添加到待处理队列的末尾,也就是等js线程空闲以后才会执行。

4、定时触发器线程,就是经常使用的setInterval与setTimeout所使用的线程,可以理解成由js引擎线程来定义一个定时器,但是定时器的计数是另开单独线程来计时并触发定时,计时时间到了以后,把要执行的回调函数里面的代码添加到待处理队列的末尾,等待js线程空闲以后执行。

5、http请求线程,在我们使用XMLHttpRequest对象发送http请求的时候,是新开一个线程请求,检测到对象状态改变时,如果绑定了回调函数,异步线程就产生状态变更事件,将这个回调里面的代码添加到js线程末尾。

**三、js引擎线程的单线程**

1、分析下面代码执行过程,以定时器触发线程为例看不同线程和js线程的执行过程:

```text
console.log('js start');
setTimeout(function(){
    console.log('时间到了')
},0);
console.log('js end');
```

在上面代码中,js代码是由js引擎线程执行的,这里要明确,js是单线程的,同一时间只能执行一个的任务,所以有多个等待任务的时候需要排队,排在前面的先执行,排在后面的要等待前面任务完成才能执行。开始的t1时间里面,代码至上而下执行,当碰到setTimeout,这是个定时器,需要计时,把这个计时的任务交给定时触发器线程(时间到了以后把要执行的代码排队到t1的后面t2时间里面),继续执行js代码。

3

最后代码执行结果为:

![img](https://pic1.zhimg.com/80/v2-7ff2169e3ee7f2818dd7013a5e84a3ec_720w.jpg)

2、分析下面代码执行过程,观察js引擎线程和GUI线程的互斥:

HTML部分:

```text
<input type="button" value='click me' id='btn'>
<div id="x"></div>
```

JavaScript部分:

```text
var btn=document.getElementById('btn');
var box=document.getElementById('x');
// wait要用于阻塞js引擎线程的执行
function wait(ms){
    let time = new Date();
    while(new Date()-time<ms){}
}

btn.onclick = function(){
    box.innerHTML = "doing something";
    wait(3000);//阻塞js引擎线程3秒
    box.innerHTML = "finish";
}
```

在上面代码中,开始的t1时间里面,代码至上而下执行,当碰到事件绑定的时候,把这个事件监听的任务交给事件触发线程,继续执行js代码。当用户点击按钮,事件触发线程监听到事件,把事件处理函数里面的代码从队列末尾插入,在t2事件执行里面有三行代码第一行是box.innerHTML = "doing something",这行代码是页面渲染,交给GUI渲染线程,由于GUI渲染线程和js引擎线程是互斥的,这个时候先让t2时间里面的其他js代码wait(3000);继续执行,把box.innerHTML = "doing something"插入t2的后面t3时间里面,执行完wait(3000)以后,最后一行是box.innerHTML = "finish",这行代码也是页面渲染,交给GUI渲染线程,由于GUI渲染线程和js引擎线程是互斥的,不能同时执行,把box.innerHTML = "finish"从队列末尾插入,变成t4时间执行。所以,最后结果是,当用户点击的时候,div里面没有内容,3秒以后直接显示finish。

5

**四、总结**

在前端学习过程中,js的单线程对大家理解同步和异步非常重要,熟悉js的单线程将让大家能够更好的理解事件,定时器和ajax请求的执行过程。更多关于“web前端培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的提升班,高品质课程助理你实现梦想。

tags:
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT