首页 > 技术文章 > 为什么说js是单线程?

aoshilin 2021-06-30 11:17 原文

为了搞清楚这个问题,我们需要先了解这几个东西:

1.什么是线程?什么是进程?他们之间的关系?

2.什么是任务队列( Event Queue ),任务分类(宏任务、微任务)?

3.什么是事件循环?

4.为什么说js是单线程?

5.为什么js要是单线程?

接下来我们一起来看一下:

1.什么是线程?什么是进程?他们之间的关系?

线程定义:线程是CPU调度的最小单位

进程定义:进程是资源分配的最小单位

抽象不太容易理解,但是有两个关键词:CPU调度、资源分配

背景:一个系统中,有很多进程,它们都会使用内存。为了确保内存不被别人使用,每个进程所能访问的内存都是圈好的。一人一份,谁也不干扰谁,进程需要管理好它的资源;线程作为进程的一部分,扮演的角色就是怎么利用中央处理器去运行代码。这其中牵扯到的最重要资源的是中央处理器和其中的寄存器,和线程的栈(stack)。这里想强调的是,线程关注的是中央处理器的运行,而不是内存等资源的管理。

总结一下,通过计算机操作系统的角度出发的。进程和线程不是同一个层面上的概念,线程是进程的一部分,线程主抓中央处理器执行代码的过程,其余的资源的保护和管理由整个进程去完成。

2.什么是任务队列( Event Queue ),任务分类(宏任务、微任务)?

定义:所有的任务可以分为同步任务异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列的机制(先进先出的机制)来进行协调。

异步任务分类:宏任务(macro-task)和微任务(micro-task)。

执行顺序:如果微任务列表里面有任务 会执行完毕后在执行宏任务。

宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)

微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)

演示代码如下:

// 这是一个同步任务
console.log('1')            --------> 直接被执行
                                      目前打印结果为:1

// 这是一个宏任务
setTimeout(function () {    --------> 整体的setTimeout被放进宏任务列表
  console.log('2')                    目前宏任务列表记为【s2】
});

new Promise(function (resolve) {
  // 这里是同步任务
  console.log('3');         --------> 直接被执行
  resolve();                          目前打印结果为:1、3
  // then是一个微任务
}).then(function () {       --------> 整体的then[包含里面的setTimeout]被放进微任务列表
  console.log('4')                    目前微任务列表记为【t45】
  setTimeout(function () {
    console.log('5')
  });
});

执行结果为:1、3、4、2、5

3.什么是事件循环?

定义:主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 不断重复的过程就是我们说的 Event Loop (事件循环)。

4.为什么说js是单线程?

浏览器是多进程的,浏览器每一个 tab 标签都代表一个独立的进程,其中浏览器渲染进程(浏览器内核)属于浏览器多进程中的一种,主要负责页面渲染,脚本执行,事件处理等
其包含的线程有:GUI 渲染线程(负责渲染页面,解析 HTML,CSS 构成 DOM 树)、JS 引擎线程、事件触发线程、定时器触发线程、http 请求线程等主要线程。

主线程:也就是 js 引擎执行的线程,这个线程只有一个,页面渲染、函数处理都在这个主线程上执行。

工作线程:也称幕后线程,这个线程可能存在于浏览器或js引擎内,与主线程是分开的,处理文件读取、网络请求等异步事件。

可以看出,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程,所以说js是单线程

5.为什么js要是单线程?

js设计为单线程还是跟他的用途有关,试想一下 如果js设计为多线程 那么同时修改和删除同一个dom 浏览器又该如何执行?

相关链接:【JS】深入理解事件循环,这一篇就够了!(必看)(https://zhuanlan.zhihu.com/p/87684858)

     JS事件循环(https://www.jianshu.com/p/184988903562)

推荐阅读