首页 > 其他分享 >关于js单线程的问题

关于js单线程的问题

时间:2023-06-16 19:23:03浏览次数:43  
标签:异步 单线程 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 事件循环

标签:异步,单线程,js,任务,线程,关于,执行
From: https://www.cnblogs.com/yolocatcat/p/17486354.html

相关文章

  • centos8使用Yum安装nodejs步骤方法、nodejs升级切换版本的方法
    先确认系统是否已经安装了epel-release包(EPEL是企业版Linux的额外软件包,是Fedora小组维护的一个软件仓库项目,为RHEL/CentOS提供他们默认不提供的软件包。):Bash#yuminfoepel-release如果有输出有关epel-release的已安装信息,则说明已经安装,如果提示没有安装或可安装,则安装......
  • tween.js简单案例
    ‘init(); animate(); functioninit(){ varoutput=document.createElement('div'); output.style.cssText='position:absolute;left:50px;top:300px;font-size:100px'; document.body.appendChild(output); v......
  • jquery根据json自动生成表格
    <!DOCTYPEhtml><html><head><metacharset="utf-8"><title>导入文件</title><linkrel="stylesheet"href="/js/bootstrap.min.css"><scriptsrc="/js/jquery.min.js&q......
  • java中xml和json转换
    packagecom.lbdz.bsf.util;importnet.sf.json.JSONObject;importnet.sf.json.JSONSerializer;importnet.sf.json.xml.XMLSerializer;/***xml和json转换*/publicclassXMLUtils{/***xml转化为字符串*@paramxml*@returnstr......
  • Fabric.js 选中元素不置顶(防止显示到顶层挡住其它元素)
     初始化画布的时候把preserveObjectStacking的属性改成true,默认是false this.canvas=newfabric.Canvas('mycanvas',{preserveObjectStacking:true}); 其它【Fabric.js元素被遮挡的部分也可以操作 】觉得很有用,记录一下,原地址:Fabric.js元素被遮挡的部分也......
  • 字符串数组不能转化对象数组,jsonArray也转化报错
    刚开始写法------错误JSONArrayjsonArray=(JSONArray)this.getJsonFilter().get("ids");PltPayDuesModel[]payDuesModels=(PltPayDuesModel[])jsonArray.toArray();报这个[Ljava.lang.Object;cannotbecastto[Ljava.lang.String;由于无法直接,因此需要曲线救国......
  • 关于vue2路由跳转问题记录
    1.vue路由间跳转和新开窗口的方式(query,params)路由间跳转配置:query方式:参数会在url中显示this.$router.push({path:'路由地址',query:{msg:'helloworld'}})params方式:传参数据不会在导航栏中显示,需要配合路由的name属性使用。this.$......
  • 包含js代码的dom元素从页面上消失后发生了什么
    最近遇到了一个问题:有一个数据看板的页面运行了n天后突然页面崩溃了,爆出了outofmemory的错误。页面不复杂,几个图表定时更新数据,实在没明白为什么长时间运行后会outofmemory。在每次请求后使用console.log(window.performance.memory); 打印出页面的内存占用情况,然后就......
  • web worker进程和线程的区别,Chrome 中有哪些常⻅进程,如果我有⼀个耗时很⻓的同步计算
    进程(Process)和线程(Thread)都是操作系统中用于多任务处理的概念。简单地说,一个进程就是一个程序的执行空间,而一个线程则是在执行空间内独立运行的执行路径。区别:进程是系统分配资源的最小单位,线程是操作系统调度的最小单位。各个进程之间是独立的,各个线程之间共享一些资源。创......
  • 直播app开发,JS 获取当天、上周、本周,下周开始时间
    直播app开发,JS获取当天、上周、本周,下周开始时间 <script>  //注释:Date.parse()//转化时间戳  //时间  varnow=newDate();//当前日期  varnowDayOfWeek=now.getDay();//今天本周的第几天  varnowDay=now.getDate();  //当前日期 ......