JS事件循環(huán)機(jī)制event loop宏任務(wù)微任務(wù)原理解析
首先看一段代碼
async function (){ await f2() console.log('f1') } async function f2(){ console.log('f2') } console.log('正常1') f1() setTimeout(()=>{ console.log('定時(shí)器') }) console.log('正常2')
正確的打印順序應(yīng)該是:正常1,f2 ,正常2,f1,定時(shí)器
為什么會(huì)出現(xiàn)這樣打印順序呢
首先javascript是一門單線程語言,在最新的HTML5中提出了Web-Worker,但javascript是單線程這一核心仍未改變。既然js是單線程,那就像只有一個(gè)窗口的銀行,客戶需要排隊(duì)一個(gè)一個(gè)辦理業(yè)務(wù),同理js任務(wù)也要一個(gè)一個(gè)順序執(zhí)行。如果一個(gè)任務(wù)耗時(shí)過長,那么后一個(gè)任務(wù)也必須等著。所以就出現(xiàn)了同步任務(wù)和異步任務(wù)。
概念
除了廣義的同步任務(wù)和異步任務(wù),對任務(wù)可以進(jìn)行更精細(xì)的區(qū)分
- macro-task(宏任務(wù)):包括整體代碼script,setTimeout,setInterval
- micro-task(微任務(wù)):Promise,process.nextTick
宏任務(wù):瀏覽器為了能夠使得JS內(nèi)部task與DOM任務(wù)能夠有序的執(zhí)行,會(huì)在一個(gè)task執(zhí)行結(jié)束后,在下一個(gè) task 執(zhí)行開始前,對頁面進(jìn)行重新渲染 (task->渲染->task->…)
鼠標(biāo)點(diǎn)擊會(huì)觸發(fā)一個(gè)事件回調(diào),需要執(zhí)行一個(gè)宏任務(wù),然后解析HTMl
微任務(wù):微任務(wù)通常來說就是需要在當(dāng)前 同步任務(wù) 執(zhí)行結(jié)束后立即執(zhí)行的任務(wù),比如對一系列動(dòng)作做出反饋,或者是需要異步的執(zhí)行任務(wù)而又不需要分配一個(gè)新的任務(wù),這樣便可以減小一點(diǎn)性能的開銷。
既然我們清楚了概念,我們再看一遍代碼
async function (){ await f2() console.log('f1') } async function f2(){ console.log('f2') } console.log('正常1') f1() setTimeout(()=>{ console.log('定時(shí)器') }) console.log('正常2')
執(zhí)行順序
首先我們進(jìn)行正常的同步流程,打印出‘正常1',接下來執(zhí)行f1()函數(shù),await后面的函數(shù)f2()會(huì)立即執(zhí)行,所以會(huì)打印'f2',繼續(xù)執(zhí)行同步代碼打印‘正常2',至此同步任務(wù)全部結(jié)束,開始執(zhí)行異步任務(wù)微任務(wù),await f2()等待f2()方法執(zhí)行完之后打印出f1,最后執(zhí)行宏任務(wù)setTimeout打印‘定時(shí)器'
這就是為什么‘正常1',正常2'會(huì)打印在‘f1'之前,因?yàn)樗形⑷蝿?wù)執(zhí)行的時(shí)候,當(dāng)前執(zhí)行棧的代碼必須已經(jīng)執(zhí)行完畢?!甪2','f1'會(huì)打印在‘定時(shí)器'之前是因?yàn)樗形⑷蝿?wù)總會(huì)在下一個(gè)宏任務(wù)之前全部執(zhí)行完畢
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 淺談JavaScript宏任務(wù)和微任務(wù)執(zhí)行順序
- 淺談js中的宏任務(wù)和微任務(wù)
- JavaScript中的宏任務(wù)和微任務(wù)執(zhí)行順序
- JavaScript宏任務(wù)和微任務(wù)區(qū)別介紹
- JavaScript?微任務(wù)和宏任務(wù)講解
- 詳解JS事件循環(huán)及宏任務(wù)微任務(wù)的原理
- JavaScript事件循環(huán)及宏任務(wù)微任務(wù)原理解析
- 淺談javascript事件環(huán)微任務(wù)和宏任務(wù)隊(duì)列原理
- JavaScript中的宏任務(wù)和微任務(wù)詳情
- JavaScript的宏任務(wù)和微任務(wù)有哪些以及怎樣執(zhí)行的詳解
相關(guān)文章
javascript中創(chuàng)建對象的三種常用方法
在javascript中創(chuàng)建對象的三種方法,腳本之家以前發(fā)布過有簡單實(shí)例版的,大家可以參考下。2010-12-12JavaScript實(shí)現(xiàn)給浮點(diǎn)數(shù)添加千分位逗號(hào)的多種方法
JavaScript 是一門強(qiáng)大的前端語言,在處理數(shù)值格式化時(shí)提供了多種方法,在開發(fā)過程中,我們經(jīng)常需要將大數(shù)字格式化,使其更具可讀性,例如,將 12000000.11 轉(zhuǎn)換為 12,000,000.11,本文將詳細(xì)介紹 JavaScript 中如何實(shí)現(xiàn)這種格式化,需要的朋友可以參考下2025-04-04微信小程序?qū)崿F(xiàn)動(dòng)態(tài)驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)動(dòng)態(tài)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05JavaScript實(shí)現(xiàn)獲取某個(gè)元素相鄰兄弟節(jié)點(diǎn)的prev與next方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)獲取某個(gè)元素相鄰兄弟節(jié)點(diǎn)的prev與next方法,涉及JavaScript基于函數(shù)的判定及調(diào)用previousSibling與nextSibling的相關(guān)技巧,需要的朋友可以參考下2016-01-01JavaScript表單即時(shí)驗(yàn)證 驗(yàn)證不成功不能提交
這篇文章主要為大家詳細(xì)介紹了JavaScript表單即時(shí)驗(yàn)證,驗(yàn)證不成功不能提交,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08