欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript運(yùn)行機(jī)制實(shí)例分析

 更新時(shí)間:2020年04月11日 12:42:40   作者:vivi_Tong  
這篇文章主要介紹了JavaScript運(yùn)行機(jī)制,結(jié)合實(shí)例形式分析JavaScript運(yùn)行機(jī)制相關(guān)原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了JavaScript運(yùn)行機(jī)制。分享給大家供大家參考,具體如下:

第一次寫(xiě)博客

目前研一第二學(xué)期,大二開(kāi)始入門(mén)前端,然而長(zhǎng)久以來(lái)都是對(duì)于框架的簡(jiǎn)單調(diào)用,并未對(duì)其進(jìn)行深入研究,因此,這個(gè)博客是作為自我督促的開(kāi)始。這篇博客的內(nèi)容源于前段時(shí)間寫(xiě)一個(gè)微信小程序前端,發(fā)現(xiàn)頁(yè)面的渲染順序總與自己的預(yù)想相違背,因此近期看了一些關(guān)于JavaScript運(yùn)行機(jī)制的博客及文檔,有了一些基本的框架,接下來(lái)就來(lái)詳細(xì)看一下我所了解到的內(nèi)容。

JavaScript執(zhí)行順序

首先,JavaScript是按照順序,一行一行執(zhí)行的,且JS只有一條線(xiàn)程,即不可能進(jìn)行兩條代碼同時(shí)執(zhí)行,也就是說(shuō),在一條代碼執(zhí)行時(shí),它后面的所有代碼都需要等待,直到該代碼執(zhí)行結(jié)束,后面的才能繼續(xù)執(zhí)行。如果是這樣,就會(huì)導(dǎo)致用戶(hù)體驗(yàn)度極其不好,例如一個(gè)請(qǐng)求發(fā)送給服務(wù)器,后續(xù)代碼就會(huì)一直等待,直到服務(wù)器返回結(jié)果,用戶(hù)才能進(jìn)行新的操作。

這又是怎么回事呢?

詳細(xì)解釋JavaScript執(zhí)行機(jī)制

JavaScript執(zhí)行棧

JavaScript是以壓棧的方式進(jìn)行代碼的執(zhí)行的,一開(kāi)始執(zhí)行時(shí)棧內(nèi)為空,當(dāng)執(zhí)行開(kāi)始,JS引擎會(huì)將代碼放入棧底,若該代碼包含其他函數(shù)的調(diào)用,則將被調(diào)用的函數(shù)放在棧頂,若該代碼未包含其他函數(shù)的調(diào)用,則執(zhí)行該函數(shù),執(zhí)行完成后出棧,以此類(lèi)推,最終直到棧為空。

JavaScript的同步任務(wù)和異步任務(wù)

事實(shí)上,真正的JS內(nèi)部分為同步任務(wù)和異步任務(wù),然而這并沒(méi)有改變JS單線(xiàn)程的特征。

  • 同步任務(wù):執(zhí)行后直接返回結(jié)果,例:console.log();c = a + b
  • 異步任務(wù):執(zhí)行后無(wú)法立刻返回結(jié)果,需要等待一定時(shí)間,才能執(zhí)行回調(diào)函數(shù),對(duì)返回結(jié)果進(jìn)行操作

系統(tǒng)來(lái)說(shuō),JS存在一個(gè)主線(xiàn)程,它會(huì)首先執(zhí)行所有同步任務(wù),而異步任務(wù)都會(huì)先進(jìn)行注冊(cè),然后主線(xiàn)程不會(huì)等待異步任務(wù)執(zhí)行結(jié)果的返回,而是繼續(xù)執(zhí)行下面的同步任務(wù)(在此過(guò)程中,如果異步任務(wù)返回結(jié)果,接下來(lái)的回調(diào)函數(shù)會(huì)放在Event Queue中等待),直到同步任務(wù)全部執(zhí)行完畢,主線(xiàn)程就會(huì)從Event Queue讀取任務(wù)進(jìn)行執(zhí)行。該過(guò)程會(huì)不斷循環(huán),即事件循環(huán)Event Loop。

事件循環(huán)是如何發(fā)生的

不覺(jué)得奇怪嗎,如果按照上述同步任務(wù)和異步任務(wù)的執(zhí)行方式,那不是一輪就可以執(zhí)行完畢嗎,又何來(lái)的Event Loop?

這是個(gè)小細(xì)節(jié),異步任務(wù)存在多個(gè)時(shí),每一個(gè)異步任務(wù)返回的結(jié)果所需的時(shí)間都是不同的,這就存在Event Queue以先進(jìn)先出的形式將返回結(jié)果進(jìn)行排隊(duì),第一個(gè)異步任務(wù)返回結(jié)果,那么就將其放在隊(duì)列的首位,接下來(lái)的異步任務(wù)緊隨其后,就這樣排成一隊(duì)。當(dāng)主線(xiàn)程空閑時(shí)(即同步任務(wù)執(zhí)行完畢后),便從Event Queue中讀取事件,放入主線(xiàn)程執(zhí)行。而循環(huán)來(lái)自于,當(dāng)Event Queue執(zhí)行完畢后,過(guò)了一段時(shí)間,又有之前的異步任務(wù)返回結(jié)果,放到Event Queue中,監(jiān)控器檢測(cè)到Event Queue為非空,主線(xiàn)程又開(kāi)始執(zhí)行Event Queue中的任務(wù)。

宏任務(wù)和微任務(wù)

在解釋定義之前,我們先對(duì)異步任務(wù)進(jìn)行說(shuō)明:

  1. 對(duì)服務(wù)器的異步請(qǐng)求:最常見(jiàn)的異步任務(wù),這涉及前后端的交互,需要服務(wù)器對(duì)請(qǐng)求進(jìn)行處理,并返回請(qǐng)求結(jié)果
  2. setTimeout和setInterval:延時(shí)操作,后者為循環(huán)操作(都涉及延時(shí)值)
  3. Promise:JS用來(lái)處理異步操作的對(duì)象
  4. process.nextTick(callback):類(lèi)似node.js版的"setTimeout",在事件循環(huán)的下一次循環(huán)中調(diào)用 callback 回調(diào)函數(shù)。

廣義上JS分為同步任務(wù)和異步任務(wù),在此對(duì)任務(wù)進(jìn)行更精細(xì)的定義:

  • macro-task(宏任務(wù)):包括整體代碼script,setTimeout,setInterval
  • micro-task(微任務(wù)):Promise,process.nextTick

在此,之所以提出宏任務(wù)和微任務(wù),是為了更好的理解事件循環(huán)!

執(zhí)行過(guò)程:

  • 主線(xiàn)程會(huì)按順序先執(zhí)行第一次循環(huán)的宏任務(wù),然后將第一次循環(huán)遇到的微任務(wù)放入微任務(wù)的Event Queue中,將遇到的宏任務(wù)放入宏任務(wù)Event Queue中,在此特別注意??!第一次循環(huán)的宏任務(wù)是整體script代碼?。?;
  • 然后后執(zhí)行微任務(wù)的Event Queue;
  • 第二次循環(huán)時(shí),會(huì)從宏任務(wù)的Event Queue中取出第一個(gè)宏任務(wù),然后執(zhí)行當(dāng)前宏任務(wù)中包含的代碼,同樣將遇到的微任務(wù)放入微任務(wù)的Event Queue中,將遇到的宏任務(wù)放入宏任務(wù)Event Queue中;
  • 再執(zhí)行當(dāng)前微任務(wù)的Event Queue中的任務(wù);
  • 第三次循環(huán),從宏任務(wù)的Event Queue中取出第二個(gè)宏任務(wù)…(以此循環(huán))

簡(jiǎn)而言之,就是先執(zhí)行宏任務(wù),再執(zhí)行微任務(wù),特別注意兩點(diǎn)即可:

  1. 第一次循環(huán)的宏任務(wù)是整體script代碼
  2. 宏任務(wù)隊(duì)列是一次循環(huán)執(zhí)行一條宏任務(wù)

這里看個(gè)例子:

 console.log('1');
 
 setTimeout(function() {
  console.log('2');
  process.nextTick(function() {
   console.log('3');
  })
  new Promise(function(resolve) {
   console.log('4');
   resolve();
  }).then(function() {
   console.log('5')
  })
 })
 process.nextTick(function() {
  console.log('6');
 })
 new Promise(function(resolve) {
  console.log('7');
  resolve();
 }).then(function() {
  console.log('8')
 })
 
 setTimeout(function() {
  console.log('9');
  process.nextTick(function() {
   console.log('10');
  })
  new Promise(function(resolve) {
   console.log('11');
   resolve();
  }).then(function() {
   console.log('12')
  })
 })
 
 //作者:ssssyoki
 //鏈接:https://juejin.im/post/59e85eebf265da430d571f89
 //來(lái)源:掘金

輸出順序?yàn)椋?/p>

1,7,6,8,2,4,3,5,9,11,10,12

總結(jié)

在此博客中,或許包含一些你未曾聽(tīng)過(guò)的名詞或方法,我并未對(duì)其進(jìn)行詳細(xì)解釋。之所以如此,是由于,于我個(gè)人,在看一些資料時(shí),經(jīng)常遇到不懂的東西,我會(huì)選擇自己進(jìn)行查閱和理解,這樣更有效于記憶和通透的理解,就跟查單詞是一樣的,如果文本里直接告訴你,反而不會(huì)重視。

感興趣的朋友可以使用在線(xiàn)HTML/CSS/JavaScript代碼運(yùn)行工具http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《JavaScript操作DOM技巧總結(jié)》、《JavaScript頁(yè)面元素操作技巧總結(jié)》、《JavaScript事件相關(guān)操作與技巧大全》、《JavaScript查找算法技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • JavaScript-定時(shí)器0~9抽獎(jiǎng)系統(tǒng)詳解(代碼)

    JavaScript-定時(shí)器0~9抽獎(jiǎng)系統(tǒng)詳解(代碼)

    這篇文章主要介紹了 JavaScript-定時(shí)器0~9抽獎(jiǎng)系統(tǒng),通過(guò)代碼實(shí)例說(shuō)明函數(shù)調(diào)用的整體操作,具體步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • JavaScript 獲取元素在父節(jié)點(diǎn)中的下標(biāo)(推薦)

    JavaScript 獲取元素在父節(jié)點(diǎn)中的下標(biāo)(推薦)

    jQuery中直接通過(guò)$(this).index()即可得到當(dāng)前元素的下標(biāo)。下面通過(guò)實(shí)例給大家介紹JavaScript 獲取元素在父節(jié)點(diǎn)中的下標(biāo),需要的朋友參考下吧
    2017-06-06
  • 利用JS來(lái)控制鍵盤(pán)的上下左右鍵(示例代碼)

    利用JS來(lái)控制鍵盤(pán)的上下左右鍵(示例代碼)

    這篇文章主要介紹了利用JS來(lái)控制鍵盤(pán)的上下左右鍵示例代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-12-12
  • 如何在uniapp中獲取可視區(qū)域的高度(uni.getSystemInfo)

    如何在uniapp中獲取可視區(qū)域的高度(uni.getSystemInfo)

    這篇文章主要給大家介紹了關(guān)于如何在uniapp中獲取可視區(qū)域的高度(uni.getSystemInfo)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用uniapp具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-04-04
  • JavaScript實(shí)現(xiàn)二分查找實(shí)例代碼

    JavaScript實(shí)現(xiàn)二分查找實(shí)例代碼

    二分查找的前提為:數(shù)組、有序。這篇文章主要介紹了JavaScript實(shí)現(xiàn)二分查找實(shí)例代碼,需要的朋友可以參考下
    2017-02-02
  • JavaScript處理變量命名的參數(shù)對(duì)象

    JavaScript處理變量命名的參數(shù)對(duì)象

    這篇文章主要介紹了JavaScript處理變量命名的參數(shù)對(duì)象,在開(kāi)發(fā)過(guò)程中,遇到一個(gè)給對(duì)象賦值的問(wèn)題,參數(shù)是通過(guò)循環(huán)變量的方式進(jìn)行處理,接下來(lái)詳細(xì)介紹需要的小伙伴可以參考一下
    2022-06-06
  • 微信小程序抽獎(jiǎng)組件的使用步驟

    微信小程序抽獎(jiǎng)組件的使用步驟

    這篇文章主要給大家介紹了關(guān)于微信小程序抽獎(jiǎng)組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • js簡(jiǎn)單判斷移動(dòng)端系統(tǒng)的方法

    js簡(jiǎn)單判斷移動(dòng)端系統(tǒng)的方法

    這篇文章主要介紹了js簡(jiǎn)單判斷移動(dòng)端系統(tǒng)的方法,通過(guò)JavaScript的navigator.userAgent相關(guān)屬性判斷訪(fǎng)問(wèn)端的系統(tǒng)類(lèi)型,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2016-02-02
  • 百度Popup.js彈出框進(jìn)化版 拖拽小框架發(fā)布 兼容IE6/7/8,Firefox,Chrome

    百度Popup.js彈出框進(jìn)化版 拖拽小框架發(fā)布 兼容IE6/7/8,Firefox,Chrome

    百度空間的彈出窗口和拖拽效果(也就是popup.js),代碼精簡(jiǎn),效果也很好,我們可以在很多大型網(wǎng)站上見(jiàn)到這種效果,在我的項(xiàng)目中也使用了該js。
    2010-04-04
  • JavaScript 中如何將秒轉(zhuǎn)換為分秒

    JavaScript 中如何將秒轉(zhuǎn)換為分秒

    JavaScript中將秒轉(zhuǎn)換為分鐘和秒,通過(guò)將秒數(shù)除以 60 得到整分鐘數(shù),獲取剩余的秒數(shù),本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-09-09

最新評(píng)論