关于js单线程的问题

为什么说 js 是单线程?

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

  1. 什么是线程?什么是进程?他们之间的关系?
  2. 什么是任务队列( Event Queue ),任务分类(宏任务、微任务)?
  3. 什么是事件循环?
  4. 为什么说 js 是单线程?
  5. 为什么 js 要是单线程?

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

  1. 什么是线程?什么是进程?他们之间的关系?
  • 线程定义:线程是 CPU 调度的最小单位

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

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

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

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

  1. 什么是任务队列( 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

  1. 什么是事件循环?

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

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

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

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

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

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

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

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

相关链接:

【JS】深入理解事件循环,这一篇就够了!(必看)

JS 事件循环

posted @ 2023-06-16 19:07  爱抽烟的王源  阅读(3)  评论(0编辑  收藏  举报