电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

深入分析JavaScript 事件循環(huán)(Event Loop)

瀏覽:47日期:2023-10-23 11:47:27

事件循環(huán)(Event Loop),是每個(gè)JS開(kāi)發(fā)者都會(huì)接觸到的概念,但是剛接觸時(shí)可能會(huì)存在各種疑惑。

眾所周知,JS是單線程的,即同一時(shí)間只能運(yùn)行一個(gè)任務(wù)。一般情況下這不會(huì)引發(fā)問(wèn)題,但是如果我們有一個(gè)耗時(shí)較多的任務(wù),我們必須等該任務(wù)執(zhí)行完畢才能進(jìn)入下一個(gè)任務(wù),然而等待的這段時(shí)間常常讓我們無(wú)法忍受,因?yàn)槲覀冞@段時(shí)間什么都不能做,包括頁(yè)面也是鎖死狀態(tài)。

好在,時(shí)代在進(jìn)步,瀏覽器向我們提供了JS引擎不具備的特性:Web API。Web API包括DOM API、定時(shí)器、HTTP請(qǐng)求等特性,可以幫助我們實(shí)現(xiàn)異步、非阻塞的行為。我們可以通過(guò)異步執(zhí)行任務(wù)的方法來(lái)解決單線程的弊端,事件循環(huán)為此而生。

提問(wèn)QAQ:為什么JavaScript是單線程的?

多個(gè)線程表示您可以同時(shí)獨(dú)立執(zhí)行程序的多個(gè)部分。確定一種語(yǔ)言是單線程還是多線程的最簡(jiǎn)單方法是看它擁有有多少個(gè)調(diào)用堆棧。JS 只有一個(gè),所以它是單線程語(yǔ)言。

將JS設(shè)計(jì)為單線程是由其用途運(yùn)行環(huán)境等因素決定的,作為瀏覽器腳本語(yǔ)言,JS的主要用途是與用戶互動(dòng),以及操作DOM。這決定了它只能是單線程,否則會(huì)帶來(lái)很復(fù)雜的同步問(wèn)題。同時(shí),單線程執(zhí)行效率高。

1. Event Loop舊印象

大家熟悉的關(guān)于事件循環(huán)的機(jī)制說(shuō)法大概是:主進(jìn)程執(zhí)行完了之后,每次從任務(wù)隊(duì)列里取一個(gè)任務(wù)執(zhí)行。如圖所示,所有的任務(wù)分為同步任務(wù)和異步任務(wù),同步任務(wù)直接進(jìn)入任務(wù)隊(duì)列-->主程序執(zhí)行;異步任務(wù)則會(huì)掛起,等待其有返回值時(shí)進(jìn)入任務(wù)隊(duì)列從而被主程序執(zhí)行。異步任務(wù)會(huì)通過(guò)任務(wù)隊(duì)列的機(jī)制(先進(jìn)先出的機(jī)制)來(lái)進(jìn)行協(xié)調(diào)。具體如圖所示:

深入分析JavaScript 事件循環(huán)(Event Loop)

同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行環(huán)境,同步的進(jìn)入主線程,即主執(zhí)行棧,異步的進(jìn)入任務(wù)隊(duì)列。主線程內(nèi)的任務(wù)執(zhí)行完畢為空,會(huì)去任務(wù)隊(duì)列讀取對(duì)應(yīng)的任務(wù),推入主線程執(zhí)行。 上述過(guò)程的不斷重復(fù)就是我們所熟悉的Event Loop (事件循環(huán))。但是promise出現(xiàn)之后,這個(gè)說(shuō)法就不太準(zhǔn)確了。

2. Event Loop 后印象

2.1 理論

這里首先用一張圖展示JavaScript的事件循環(huán):

深入分析JavaScript 事件循環(huán)(Event Loop)

直接看這張圖,可能黑人問(wèn)號(hào)已經(jīng)出現(xiàn)在同學(xué)的腦海。。。

這里將task分為兩大類(lèi),分別是macroTask(宏任務(wù))和microTask(微任務(wù)).一次事件循環(huán):先運(yùn)行macroTask隊(duì)列中的一個(gè),然后運(yùn)行microTask隊(duì)列中的所有任務(wù)。接著開(kāi)始下一次循環(huán)(只是針對(duì)macroTask和microTask,一次完整的事件循環(huán)會(huì)比這個(gè)復(fù)雜的多)。

那什么是macroTask?什么是microTask呢?

JavaScript引擎把我們的所有任務(wù)分門(mén)別類(lèi),一部分歸為macroTask,另外一部分歸為microTack,下面是類(lèi)別劃分:

macroTask:

setTimeout setInterval setImmediate requestAnimationFrame I/O UI rendering

microTask:

process.nextTick Promise Object.observe MutationObserver

我們所熟悉的定時(shí)器就屬于macroTask,僅僅了解macroTask的機(jī)制還是不夠的。為直觀感受兩種隊(duì)列的區(qū)別,下面上代碼進(jìn)行實(shí)踐感知。

2.2 實(shí)踐

以setTimeout、process.nextTick、promise為例直觀感受下兩種任務(wù)隊(duì)列的運(yùn)行方式。

console.log(’main1’);process.nextTick(function() { console.log(’process.nextTick1’);});setTimeout(function() { console.log(’setTimeout’); process.nextTick(function() { console.log(’process.nextTick2’); });}, 0);new Promise(function(resolve, reject) { console.log(’promise’); resolve();}).then(function() { console.log(’promise then’);});console.log(’main2’);

別著急看答案,先以上面的理論自己想想,運(yùn)行結(jié)果會(huì)是啥?

最終結(jié)果是這樣的:

main1promisemain2process.nextTick1promise then

// 第二次事件循環(huán)setTimeoutprocess.nextTick2

process.nextTick 和 promise then在 setTimeout 前面輸出,已經(jīng)證明了macroTask和microTask的執(zhí)行順序。但是有一點(diǎn)必須要指出的是。上面的圖容易給人一個(gè)錯(cuò)覺(jué),就是主進(jìn)程的代碼執(zhí)行之后,會(huì)先調(diào)用macroTask,再調(diào)用microTask,這樣在第一個(gè)循環(huán)里一定是macroTask在前,microTask在后。

但是最終的實(shí)踐證明:在第一個(gè)循環(huán)里,process.nextTick1和promise then這兩個(gè)microTask是在setTimeout這個(gè)macroTask里之前輸出的,這是因?yàn)镻romises/A+規(guī)范規(guī)定主進(jìn)程的代碼也屬于macroTask。

主進(jìn)程這個(gè)macroTask(也就是main1、promise和main2)執(zhí)行完了,自然會(huì)去執(zhí)行process.nextTick1和promise then這兩個(gè)microTask。這是第一個(gè)循環(huán)。之后的setTimeout和process.nextTick2屬于第二個(gè)循環(huán)

別看上面那段代碼好像特別繞,把原理弄清楚了,都一樣 ~

requestAnimationFrame、Object.observe(已廢棄) 和 MutationObserver這三個(gè)任務(wù)的運(yùn)行機(jī)制大家可以從上面看到,不同的只是具體用法不同。重點(diǎn)說(shuō)下UI rendering。在HTML規(guī)范:event-loop-processing-model里敘述了一次事件循環(huán)的處理過(guò)程,在處理了macroTask和microTask之后,會(huì)進(jìn)行一次Update the rendering,其中細(xì)節(jié)比較多,總的來(lái)說(shuō)會(huì)進(jìn)行一次UI的重新渲染。

3. 小結(jié)

總而言之,記住一次事件循環(huán):先運(yùn)行macroTask隊(duì)列中的一個(gè),然后運(yùn)行microTask隊(duì)列中的所有任務(wù)。接著開(kāi)始下一次循環(huán)。

參考文獻(xiàn):

JavaScript Event Loop相關(guān)原理解析 深入理解事件循環(huán)機(jī)制 JavaScript運(yùn)行機(jī)制

以上就是深入分析JavaScript 事件循環(huán)(Event Loop)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript 事件循環(huán)(Event Loop)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 挨踢网-大家的导航!| 细胞染色-流式双标-试剂盒免费代做-上海研谨生物科技有限公司 | 小型气象站_便携式自动气象站_校园气象站-竞道气象设备网 | 上海盐水喷雾试验机_两厢式冷热冲击试验箱-巨怡环试 | 可程式恒温恒湿试验箱|恒温恒湿箱|恒温恒湿试验箱|恒温恒湿老化试验箱|高低温试验箱价格报价-广东德瑞检测设备有限公司 | 宁波普瑞思邻苯二甲酸盐检测仪,ROHS2.0检测设备,ROHS2.0测试仪厂家 | 鲁尔圆锥接头多功能测试仪-留置针测试仪-上海威夏环保科技有限公司 | 气力输送_输送机械_自动化配料系统_负压吸送_制造主力军江苏高达智能装备有限公司! | 日本SMC气缸接头-速度控制阀-日本三菱伺服电机-苏州禾力自动化科技有限公司 | 成都亚克力制品,PVC板,双色板雕刻加工,亚克力门牌,亚克力标牌,水晶字雕刻制作-零贰捌广告 | 合肥办公室装修 - 合肥工装公司 - 天思装饰 | 深圳市索富通实业有限公司-可燃气体报警器 | 可燃气体探测器 | 气体检测仪 | 座椅式升降机_无障碍升降平台_残疾人升降平台-南京明顺机械设备有限公司 | 优考试_免费在线考试系统_培训考试系统_题库系统_组卷答题系统_匡优考试 | 首页_欧瑞传动官方网站--主营变频器、伺服系统、新能源、软起动器、PLC、HMI | 威廉希尔WilliamHill·足球(中国)体育官方网站 | 产业规划_产业园区规划-产业投资选址及规划招商托管一体化服务商-中机院产业园区规划网 | 涡街流量计_LUGB智能管道式高温防爆蒸汽温压补偿计量表-江苏凯铭仪表有限公司 | 磁粉制动器|张力控制器|气胀轴|伺服纠偏控制器整套厂家--台灵机电官网 | 氢氧化钙设备_厂家-淄博工贸有限公司 | 隧道烘箱_隧道烘箱生产厂家-上海冠顶专业生产烘道设备 | 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 都江堰招聘网-都江堰人才网 都江堰人事人才网 都江堰人才招聘网 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 双杰天平-国产双杰电子天平-美国双杰-常熟双杰仪器 | 上海APP开发-APP制作-APP定制开发-上海APP开发制作公司-咏熠科技 | 热处理炉-退火炉-回火炉设备厂家-丹阳市电炉厂有限公司 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 集装箱箱号识别_自重载重图像识别_铁路车号自动识别_OCR图像识别 | 体坛网_体坛+_体坛周报新闻客户端| Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 【法利莱住人集装箱厂家】—活动集装箱房,集装箱租赁_大品牌,更放心 | 龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司_龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司 | 培训中心-海南香蕉蛋糕加盟店技术翰香原中心官网总部 | 济南办公室装修-厂房装修-商铺装修-工装公司-山东鲁工装饰设计 | 深圳宣传片制作-企业宣传视频制作-产品视频拍摄-产品动画制作-短视频拍摄制作公司 | 对夹式止回阀厂家,温州对夹式止回阀制造商--永嘉县润丰阀门有限公司 | 旋振筛|圆形摇摆筛|直线振动筛|滚筒筛|压榨机|河南天众机械设备有限公司 | 昆明挖掘机修理厂_挖掘机翻新再制造-昆明聚力工程机械维修有限公司 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 保温杯,儿童婴童奶瓶,运动水壶「广告礼品杯定制厂家」超朗保温杯壶 |