JS运行机制

什么是进程?

  • 我们都知道,CPU是计算机的核心,承担所有的计算任务
  • 官网说法,进程CPU资源分配的最小单位
  • 字面意思就是进行中的程序,我将它理解为一个可以独立运行且拥有自己的资源空间的任务程序
  • 进程包括运行中的程序和程序所使用到的内存和系统资源
  • CPU可以有很多进程,我们的电脑每打开一个软件就会产生一个或多个进程,为什么电脑运行的软件多就会卡,是因为CPU给每个进程分配资源空间,但是一个CPU一共就那么多资源,分出去越多,越卡,每个进程之间是相互独立的,CPU在运行一个进程时,其他的进程处于非运行状态,CPU使用 时间片轮转调度算法 来实现同时运行多个进程

什么是线程?

  • 线程是CPU调度的最小单位
  • 线程是建立在进程的基础上的一次程序运行单位,通俗点解释线程就是程序中的一个执行流,一个进程可以有多个线程
  • 一个进程中只有一个执行流称作单线程,即程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行
  • 一个进程中有多个执行流称作多线程,即在一个程序中可以同时运行多个不同的线程来执行不同的任务, 也就是说允许单个程序创建多个并行执行的线程来完成各自的任务

进程和线程的区别?

  • 进程是操作系统分配资源的最小单位,线程是程序执行的最小单位
  • 一个进程由一个或多个线程组成,线程可以理解为是一个进程中代码的不同执行路线
  • 进程之间相互独立,但同一进程下的各个线程间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号)
  • 调度和切换:线程上下文切换比进程上下文切换要快得多

多进程和多线程

-多进程:多进程指的是在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态。多进程带来的好处是明显的,比如大家可以在网易云听歌的同时打开编辑器敲代码,编辑器和网易云的进程之间不会相互干扰

  • 多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务

浏览器

浏览器是多进程的

  • 拿Chrome来说,我们每打开一个窗口就会产生一个进程,我们使用Chrome打开很多标签页不关,电脑会越来越卡,很耗CPU。

浏览器包含哪些进程?

  • Browser进程(浏览器主进程
    1、浏览器的主进程(负责协调、主控),该进程只有一个
    2、负责浏览器界面显示,与用户交互。如前进,后退等
    3、负责各个页面的管理,创建和销毁其他进程
    4、将渲染(Renderer)进程得到的内存中的Bitmap(位图),绘制到用户界面上
    5、网络资源的管理,下载等
  • 第三方插件进程
    1、每种类型的插件对应一个进程,当使用该插件时才创建
  • GPU进程
    1、该进程也只有一个,用于3D绘制等等
  • 渲染进程(重要)
    1、即通常所说的浏览器内核(Renderer进程,内部是多线程)
    2、每个Tab页面都有一个渲染进程,互不影响
    3、主要作用为页面渲染,脚本执行,事件处理等
    4、渲染进程包括:GUI渲染线程(UI、DOM树、CSS规则树、Rendering Tree(渲染树)...)
浏览器进程工作

1、Browser主进程 收到用户请求,首先需要获取页面内容(如通过网络下载资源),随后将该任务通过RendererHost接口传递给Render渲染进程
2、Render渲染进程 的Renderer接口收到消息,简单解释后,交给渲染线程GUI,然后开始渲染
3、GUI渲染线程接收请求,加载网页并渲染网页,这其中可能需要 Browser主进程 获取资源和需要 GPU进程 来帮助渲染
4、当然可能会有JS线程操作DOM(这可能会造成回流并重绘)
5、最后Render渲染进程 将结果传递给 Browser主进程
6、Browser主进程 接收到结果并将结果绘制出来

为什么JavaScript是单线程?

  • JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。
  • JavaScript作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准,如果设计多线程,JavaScript会变行很复杂(个人觉得会有很多线程锁的操作问题)。所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征。
  • 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

任务队列【先进先出

  • js单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
  • 任务可以分成两种,一种是同步任务(主线程任务),另一种是异步任务。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
  • 任务队列分为宏任务和微任务,微任务优先宏任务。为什么优先?没有找到答案,个人认为主线程任务也是宏任务,宏任务执行完马上找微任务,微任务执行完再马上执行宏任务,这样行成一个事件循环
  • 宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
  • 微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)
  • 异步执行的运行机制

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。先执行微任务再执行宏任务
(4)主线程不断重复上面的第三步,不断的去检查任务队列是否有可执行的任务。

  • 只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

事件和回调函数

  • "任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
  • "任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。
  • 所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
  • "任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。但是"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

Event Loop(事件循环,主线程任务全部执行完成再找任务队列是否有任务,如果有,先执行队列中的微任务再执行队列中的宏任务)

  • 是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
  • 在JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。
宏任务
  • 主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务
  • 主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)
    image.png
//宏任务和微任务例子:
console.log('script start');

setTimeout(function() {
  console.log('setTimeout1');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

1、整体 script 作为第一个宏任务进入主线程,遇到 console.log,输出 script start。
2、遇到 setTimeout,其回调函数被分发到队列任务中的宏任务队列中。
3、遇到 Promise,其 then函数被分到到队列任务中的微任务队列中,记为 then1,之后又遇到了 then 函数,将其分到队列任务中的微任务队列中,记为 then2。
4、遇到 console.log,输出 script end。
5、此时的队列任务表示为: [ [ then1 , then2 ] , [ setTimeout ]], 再循环执行,输出 promise1 - promise2 - setTimeout,

  • 整个输出流程为:script start - script end - promise1 - promise2 - setTimeout
  • 小知识:
    1、W3C在HTML中规定setTimeout的最小间隔时间是4毫秒;setInterval的最小间隔时间是10毫秒,如果没有设置时间,就自动按最小间隔时间。
    2、需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。定时器的执行时间会大于指定的时间执行,因为并不是指定的时间执行,而是等主线程完全执行成完后再执行指定的时间执行的定时器。
    3、浏览器工作流程:构建DOM -> 构建CSSOM -> 构建渲染树 -> 布局 -> 绘制。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,720评论 1 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,536评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,603评论 2 9
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,190评论 4 8