为了搞清楚这个问题,我们需要先了解这几个东西:
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,任务,线程,进程,执行 From: https://www.cnblogs.com/caihongmin/p/16768430.html