一篇文章帶你了解vue.js的事件循環(huán)機(jī)制
一、事件循環(huán)機(jī)制介紹
JS是單線程的語言,瀏覽器和Node.js定義了各自的Event Loop(事件循環(huán)機(jī)制)則是用來解決異步問題。將程序分為“主線程(執(zhí)行棧)”與“Event Loop線程”,“主線程”自上而下依次執(zhí)行同步任務(wù),“Event Loop線程”將異步任務(wù)推入宏任務(wù)隊(duì)列與微任務(wù)隊(duì)列去執(zhí)行。
事件循環(huán)機(jī)制從整體上告訴了我們 JavaScript 代碼的執(zhí)行順序 Event Loop 即事件循環(huán),是指瀏覽器或Node 的一種解決javaScript 單線程運(yùn)行時(shí)不會(huì)阻塞的一種機(jī)制,也就是我們經(jīng)常使用異步的原理。“Event Loop線程”先執(zhí)行宏任務(wù)隊(duì)列,然后執(zhí)行微任務(wù)隊(duì)列,若微任務(wù)在執(zhí)行過程中產(chǎn)生了新的微任務(wù),則繼續(xù)執(zhí)行微任務(wù),微任務(wù)執(zhí)行完畢后,再回到宏任務(wù)中進(jìn)行下一輪循環(huán)。即繼續(xù)先執(zhí)行宏任務(wù)隊(duì)列,再執(zhí)行 微任務(wù)隊(duì)列。
宏任務(wù):
script(整體代碼)/setTimeout/setInterval/setImmediate/ I/O / UI Rendering
微任務(wù):
process.nextTick()/Promise/Async、Await(實(shí)際就是Promise)/MutationObserver(html5新特性)
setTimeout 和 setInterval 等都是任務(wù)源,真正進(jìn)入任務(wù)隊(duì)列的是他們分發(fā)的任務(wù)。
優(yōu)先級
setTimeout = setInterval 一個(gè)隊(duì)列setTimeout > setImmediate process.nextTick > Promise
二、經(jīng)典事件循環(huán)面試題
1.在下面這段代碼是面試中關(guān)于這類問題的經(jīng)典考題,其中包含了同步、異步任務(wù),幾個(gè)輸出的先后順序是怎樣的。
setTimeout(function(){ console.log('1') }); new Promise(function(resolve){ console.log('2'); resolve(); }).then(function(){ console.log('3') }); console.log('4'); // 2,4,3,1
首先進(jìn)行任務(wù)劃分,同步任務(wù):new Promise()
、console.log('4')
;宏任務(wù): setTimeout()
;微任務(wù):Promise().then()
;Event Loop
依次將同步任務(wù)推入執(zhí)行棧并執(zhí)行,當(dāng)遇到宏任務(wù)或微任務(wù)時(shí),推到宏任務(wù)或微任務(wù)隊(duì)列中。先執(zhí)行同步任務(wù),同步隊(duì)列執(zhí)行完畢,會(huì)去微隊(duì)列取任務(wù),直到微隊(duì)列清空,再去宏隊(duì)列取任務(wù)執(zhí)行。故此段程序執(zhí)行順序?yàn)椋?/p>
new Promise()
、console.log('4')
、Promise().then()
、setTimeout()
。
2.示例2
答案輸出為:async2 end => Promise => async1 end => promise1 => promise2 => setTimeout
3.示例3
mounted(){ this.test(); }, methods:{ test(){ console.log('script start'); this.async1(); setTimeout(function() { console.log('setTimeout') }, 0); new Promise(resolve => { console.log('Promise') resolve() }) .then(function() { console.log('promise1') }) .then(function() { console.log('promise2') }) console.log('script end') }, async async1() { await this.async2() console.log('async1 end') }, async async2() { console.log('async2 end') }, }
新版的chrome瀏覽器中不是如上打印的,因?yàn)閏hrome優(yōu)化了,await變得更快了,輸出為:
// script start => async2 end => Promise => script end => async1 end => promise1 => promise2
分析這段代碼:
- 執(zhí)行代碼,輸出script start。
- 執(zhí)行async1(),會(huì)調(diào)用async2(),然后輸出async2 end,此時(shí)將會(huì)保留async1函數(shù)的上下文,然后跳出async1函數(shù)。
- 遇到setTimeout,產(chǎn)生一個(gè)宏任務(wù)
- 執(zhí)行Promise,輸出Promise。遇到then,產(chǎn)生第一個(gè)微任務(wù)
- 繼續(xù)執(zhí)行代碼,輸出script end
- 代碼邏輯執(zhí)行完畢(當(dāng)前宏任務(wù)執(zhí)行完畢),開始執(zhí)行當(dāng)前宏任務(wù)產(chǎn)生的微任務(wù)隊(duì)列,輸出promise1,該微任務(wù)遇到then,產(chǎn)生一個(gè)新的微任務(wù)
- 執(zhí)行產(chǎn)生的微任務(wù),輸出promise2,當(dāng)前微任務(wù)隊(duì)列執(zhí)行完畢。執(zhí)行權(quán)回到async1
- 執(zhí)行await,實(shí)際上會(huì)產(chǎn)生一個(gè)promise返回,即
- let promise_ = new Promise((resolve,reject){ resolve(undefined)})
- 執(zhí)行完成,執(zhí)行await后面的語句,輸出async1 end 最后,執(zhí)行下一個(gè)宏任務(wù),即執(zhí)行setTimeout,輸出setTimeout
- 注意以上分析是舊版瀏覽器await執(zhí)行慢導(dǎo)致async1在微任務(wù)執(zhí)行后執(zhí)行。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Element-ui?DatePicker日期選擇器基礎(chǔ)用法示例
這篇文章主要為大家介紹了Element-ui?DatePicker日期選擇器基礎(chǔ)用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Vue使用Composition?API生成計(jì)算屬性computed
這篇文章主要為大家詳細(xì)介紹了Vue如何使用Composition?API實(shí)現(xiàn)生成計(jì)算屬性computed,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-06-06Vue3項(xiàng)目中引入ElementUI并使用的示例詳解
ElementUI是一個(gè)強(qiáng)大的PC端UI組件框架,它不依賴于vue,但是卻是當(dāng)前和vue配合做項(xiàng)目開發(fā)的一個(gè)比較好的ui框架,本文主要介紹了如何在vue3中引入使用ElementUI,需要的可以參考一下2023-06-06vue3使用xgPalyer實(shí)現(xiàn)截圖功能的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何在vue3中使用xgPalyer截圖功能,以及自定義插件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02vue本地模擬服務(wù)器請求mock數(shù)據(jù)的方法詳解
這篇文章主要給大家介紹了關(guān)于vue本地模擬服務(wù)器請求mock數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-03-03Vue3中element-plus全局使用Icon圖標(biāo)的過程詳解
我們在用vue開發(fā)網(wǎng)站的時(shí)候,往往圖標(biāo)是起著很重要的作,這篇文章主要給大家介紹了關(guān)于Vue3中element-plus全局使用Icon圖標(biāo)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01Vue3實(shí)現(xiàn)word轉(zhuǎn)成pdf代碼的方法
在Vue 3中,前端無法直接將Word文檔轉(zhuǎn)換為PDF,因?yàn)閃ord文檔的解析和PDF的生成通常需要在后端進(jìn)行這篇文章主要介紹了Vue3實(shí)現(xiàn)word轉(zhuǎn)成pdf代碼的方法,需要的朋友可以參考下,2023-07-07