JS代码执行机制-单线程-事件循环

1.JS为什么是单线程?

进程:正在运行中的应用程序。每个进程都自己独立的内存空间。例如:打开的浏览器就是一个进程。

线程:进程的子集,是独立的。线程在共享的内存空间中运行。

javascript语言在设计之时有一个十分重要的需求需要实现,那就是操作DOM节点,设想一下假如JS是多线程运行,此时线程1中代码将DOM_1节点设置为隐藏,线程2中代码将DOM_1节点设置为显示,那么此时界面中到底会被渲染成什么样呢?究竟是隐藏节点还是显示节点呢?在茫茫多的DOM操作上都可能有冲突操作,增加了程序的复杂性,所以为了避免出现类似问题,JS被设计成为单线程执行,最新的HTML5中新增的Web-Worker是一个被阉割的多线程,如果你有尝试使用过,你可能会知道在Web-Worker中无法操作DOM节点。

2.单线程带来的问题?

单线程运行好比咱们现在排队做核酸!大家排队依次打开健康码,待工作人员扫码录入后领取棉签,随后到医生那做核酸采样。每次前面的人做完,后面的人才能继续做,但是有的时候前面一位已经做完,后面这位的健康码因为网络原因,设备原因迟迟无法打开,会导致后面几十人都被耽误,这就是单线程运行带来问题,如何解决这个问题?工作人员会讲这位同志请离队伍,等他在边上将健康码打开完毕以后再将他重新塞入队伍进行核酸采样,在JS单线程运行机制中设计者也用类似的规则来处理任务,这个规则叫做事件循环。

3.JS的事件循环。

当我们编写好一段JS代码,他会如何执行?JS引擎将可执行代码由上至下依次入栈(调用栈)执行,首先会判断执行函数为同步执行函数还是异步执行函数,假如为同步任务,则直接进入主线程运行,当运行完毕并返回结果再开始下一个,如果为异步任务则会将这个执行函数塞入一个 event table中执行,并注册回调函数,不等待运行完毕就继续开始下一个任务(不等待避免阻塞),当这个异步任务执行完毕,此任务回调函数被塞入任务队列。当主线程的同步任务全部执行完毕,JS引擎会去任务队列中拿取一个任务置入主线程执行,当主线程任务再次执行完毕,JS引擎会再次去到任务队列拿取并执行,如此反复构成事件循环,推动JS代码不断运行。

盗个图
c75c10385343fbf22e77b280417e7f8764388fc6.jpg

4.关于单线程与异步任务的理解。

为什么说JS是单线程但是同时又能够做其他事情,比如定时器,http请求等,那是因为其宿主对象(浏览器进程)开启了多个线程来处理这些事情,包含的线程如下:

1.JS引擎线程:
“JavaScript 引擎”通常被称作一种虚拟机。也称为JS内核,这个线程就是我们平时说的单线程,负责处理Javascript脚本程序。(例如V8引擎),

• JS引擎线程负责解析Javascript脚本,运行代码。

• JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序。

2.GUI渲染线程:

  • 负责渲染页面,解析HTML,CSS,构建DOM tree,CSS tree。
  • 当界面需要重绘 repaint,重排reflow(回流)时该线程就会执行(重排重绘,像极了顶点着色器和片元着色器)
  • 注意这里GUI渲染线程和JS引擎线程互斥,一个运行另外一个就会挂起,这是必要的,这是为了避免DOM操作和呈现上的冲突,他们不能同时运行,而且他们中的一方执行的时间过长的话,用户会感受到卡顿,因为他们相互阻塞。

3.事件触发线程
当事件符合触发条件被触发时,该线程会把对应的事件回调函数添加到消息队列的队尾,等待JS引擎的处理。

4.定时触发器线程
浏览器定时计数器并不是由JS引擎计数的,因为JS引擎是单线程的,如果JS引擎线程处于阻塞线程状态就会影响计数的准确。因此通过另外独立的线程来计时并触发定时是更为合理的方案。

5、异步http请求线程
http请求是在XMLHttpRequest连接后通过浏览器新开一个线程请求。
请求完成有结果之后,将检测到状态变更,如果设置有回调函数,异步http请求线程就会将该请求的回调函数添加到消息队列中,等待JS引擎处理。

异步任务在如何执行:1.通知任务开始执行这个步骤在JS主线程中执行。2.任务执行在对应的线程中完成。3.任务执行完毕,将其回调函数置入任务队列,等待主线程拉取执行,注意异步任务有微任务和宏任务之分,简单理解为promise相关为微任务,他的优先级会在宏任务之前,JS始终会先执行微任务,再执行宏任务。

盗个图


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容