最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript運行機制實例分析

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

本文實例講述了JavaScript運行機制。分享給大家供大家參考,具體如下:

第一次寫博客

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

JavaScript執(zhí)行順序

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

這又是怎么回事呢?

詳細解釋JavaScript執(zhí)行機制

JavaScript執(zhí)行棧

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

JavaScript的同步任務和異步任務

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

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

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

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

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

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

宏任務和微任務

在解釋定義之前,我們先對異步任務進行說明:

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

廣義上JS分為同步任務和異步任務,在此對任務進行更精細的定義:

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

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

執(zhí)行過程:

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

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

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

這里看個例子:

 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
 //來源:掘金

輸出順序為:

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

總結(jié)

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

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

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

希望本文所述對大家JavaScript程序設計有所幫助。

相關(guān)文章

  • javascript 常用功能總結(jié)

    javascript 常用功能總結(jié)

    javascript 常用功能總結(jié),學習js的朋友可以參考下
    2012-03-03
  • js驗證框架之RealyEasy驗證詳解

    js驗證框架之RealyEasy驗證詳解

    這篇文章主要為大家詳細介紹了js驗證框架之RealyEasy驗證,記錄了RealyEasy驗證的使用步驟,感興趣的小伙伴們可以參考一下
    2016-06-06
  • JavaScript實現(xiàn)自己的DOM選擇器原理及代碼

    JavaScript實現(xiàn)自己的DOM選擇器原理及代碼

    實現(xiàn)自己的DOM選擇器時匹配行為也應該和瀏覽原生匹配行為一致,接下來本文將詳細介紹下實現(xiàn)思路及方法,感興趣的你可以參考下或許對你鞏固知識有所幫助
    2013-03-03
  • 微信小程序?qū)崿F(xiàn)輪播圖(適配機型)

    微信小程序?qū)崿F(xiàn)輪播圖(適配機型)

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)輪播圖,適配機型,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • JS取得絕對路徑的實現(xiàn)代碼

    JS取得絕對路徑的實現(xiàn)代碼

    這篇文章主要介紹了JS取得絕對路徑的實現(xiàn)代碼,需要的朋友可以參考下
    2015-01-01
  • JavaScript處理變量命名的參數(shù)對象

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

    這篇文章主要介紹了JavaScript處理變量命名的參數(shù)對象,在開發(fā)過程中,遇到一個給對象賦值的問題,參數(shù)是通過循環(huán)變量的方式進行處理,接下來詳細介紹需要的小伙伴可以參考一下
    2022-06-06
  • BootStrap中的模態(tài)框(modal,彈出層)功能示例代碼

    BootStrap中的模態(tài)框(modal,彈出層)功能示例代碼

    bootstrap中的模態(tài)框(modal),不同于Tooltips,模態(tài)框以彈出對話框的形式出現(xiàn),具有最小和最實用的功能集。這篇文章主要介紹了BootStrap中的模態(tài)框(modal,彈出層),需要的朋友可以參考下
    2018-11-11
  • JavaScript更改字符串的大小寫

    JavaScript更改字符串的大小寫

    在javascript中涉及字符串大小寫轉(zhuǎn)換的方法有4個:toLowerCase()、toLocaleLowerCase()、toUpperCase()及toLocaleUpperCase()。今天我們主要來用下toUpperCase()和toLowerCase()方法。
    2015-05-05
  • js跳轉(zhuǎn)頁面方法總結(jié)

    js跳轉(zhuǎn)頁面方法總結(jié)

    本篇文章主要是對js跳轉(zhuǎn)頁面方法進行了詳細的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 使用RN Animated做一個“添加購物車”動畫的方法

    使用RN Animated做一個“添加購物車”動畫的方法

    這篇文章主要介紹了使用RN Animated做一個“添加購物車”動畫的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09

最新評論

鲁山县| 临桂县| 乌审旗| 裕民县| 历史| 色达县| 扎鲁特旗| 东安县| 都昌县| 奇台县| 陈巴尔虎旗| 马公市| 克拉玛依市| 保靖县| 安化县| 孟州市| 罗定市| 义马市| 前郭尔| 防城港市| 黎平县| 正安县| 微山县| 宜兴市| 长泰县| 明溪县| 包头市| 习水县| 徐汇区| 阿合奇县| 抚顺县| 曲阳县| 丰城市| 盘锦市| 巴塘县| 育儿| 筠连县| 南汇区| 新乡县| 渭源县| 和龙市|