<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何理解單線程的JavaScript及其工作原理

          共 2600字,需瀏覽 6分鐘

           ·

          2021-08-13 16:13

          點擊上方 前端瓶子君,關(guān)注公眾號

          回復(fù)算法,加入前端編程面試算法每日一題群

          隨著JavaScript的日益流行,團隊也利用其在前端,后端,混合APPS,嵌入式設(shè)備以及更多設(shè)備等開發(fā)棧中諸多層面的支持,JavaScript能創(chuàng)造出令人驚嘆的軟件,開發(fā)就必須更加深入了解JavaScript語言的內(nèi)部工作機制!

          此篇文章會詳細地研究并解釋JavaScript的工作原理,通過了解這些細節(jié),通過合理地使用提供的APIs,你將能夠?qū)懗龈玫模亲枞某绦颉?/p>

          一、單線程的來源

          幾乎所有人都已經(jīng)聽過V8引擎的概念,并且很多人知道JavaScript是單線程的,JavaScript作為瀏覽器腳本語言,它的主要用途是與用戶交互,那么為什么JavaScript是單線程呢?如果JavaScript是多線程,當(dāng)頁面更新內(nèi)容的時候、用戶又觸發(fā)了交互,這時候線程間的同步問題會變得很復(fù)雜,為了避免復(fù)雜性,故JavaScript被設(shè)計成單線程。

          二、JavaScript引擎

          谷歌V8引擎是一個流行的JavaScript引擎。這里有一個簡單的視圖來描繪其大概模樣。

          image.png

          引擎包括兩個組件:

          • 內(nèi)存堆——進行內(nèi)存分配的區(qū)域
          • 調(diào)用棧——代碼執(zhí)行時棧中的位置

          三、運行時

          幾乎每個JavaScript開發(fā)者都使用過一些瀏覽器 API(比如setTimeout)。然而這些API并不是引擎所提供的。這些Web API是瀏覽器提供的,還有DOM事件,AJAX及其它。它們怎么執(zhí)行呢,實際情況有點復(fù)雜。

          于是乎,就有了如此流行的事件循環(huán)(也稱event loop或事件輪詢)和回調(diào)隊列。

          四、調(diào)用棧

          前面我們說過,JavaScript是單線程的編程語言,這意味著只有一個調(diào)用棧。這樣它只能一次做一件事情。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu)。當(dāng)執(zhí)行進入一個函數(shù),把它置于棧的底部。如果從函數(shù)中返回則從棧底部移除函數(shù)。這就是調(diào)用棧所做的事情。
          舉個??子,看如下代碼:

          fucntion multiply(x,y) {
              return x * y;
          }
          function printSquare(x{
              var s = mulitiply(x,x);
              console.log(s);
          }
          printSquare(s);
          復(fù)制代碼

          當(dāng)引擎開始執(zhí)行這段代碼的時候,調(diào)用棧會被清空,之后產(chǎn)生如下步驟:

          image.png

          五、堆棧溢出

          一旦達到最大調(diào)用棧大小的時候發(fā)生。這種情況相當(dāng)容易發(fā)生。特別是當(dāng)你使用遞歸時,看下面的代碼:

          function foo () {
              foo();
          }
          foo();
          復(fù)制代碼

          當(dāng)引擎開始執(zhí)行這段代碼的時候,它開始調(diào)用foo函數(shù)。這個函數(shù),然而會遞歸并開始調(diào)用其自身而沒有任何結(jié)束條件。所以在每步執(zhí)行過程中,調(diào)用堆棧會反復(fù)添加foo函數(shù)。就會出現(xiàn)如下情況:

          當(dāng)調(diào)用棧中的函數(shù)調(diào)用次數(shù)超過了調(diào)用棧的實際大小,瀏覽器決定拋出一個錯誤,如下圖所示:
          小伙伴們可以自己在瀏覽器的控制臺里試試!

          六、事件循環(huán)(Event Loop)

          又該拿出那張經(jīng)典的圖了~

          image.png

          Event Loop 負(fù)責(zé)執(zhí)行代碼、收集和處理事件以及執(zhí)行隊列中的子任務(wù)。

          具體包括:

          • Javascript 有一個主線程和執(zhí)行棧,所有的任務(wù)都會被放到調(diào)用棧等待主線程執(zhí)行
          • 同步任務(wù)會被放在調(diào)用棧中,按照順序等待主線程依次執(zhí)行
          • 主線程之外存在一個任務(wù)隊列,所有任務(wù)在主線程中以執(zhí)行棧的方式運行
          • 同步任務(wù)都在主線程上執(zhí)行,棧中代碼在執(zhí)行的時候會調(diào)用 Web API,此時會產(chǎn)生一些異步任務(wù)
          • 異步任務(wù)會在有了結(jié)果(比如被監(jiān)聽的事件發(fā)生時)后,將注冊的回調(diào)函數(shù)放入任務(wù)隊列中
          • 執(zhí)行棧中任務(wù)執(zhí)行完畢后,此時主線程處于空閑狀態(tài),會從任務(wù)隊列中獲取任務(wù)進行處理

          以上過程會不斷重復(fù),這就是瀏覽器的運行機制,也是Event Loop。

          最后

          Event Loop 我們還得繼續(xù),理解它是突破前端第一層天花板的畢竟之路!


          關(guān)于本文

          來源:_啊嗚

          https://juejin.cn/post/6991241111167565860


          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對你有幫助,在看」是最大的支持
           》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持



          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩爱操视频 | 一本久久精品一区二区 | 91人妻人人爽人人 | 琪琪色see,www,Cσm | www.俺去啦 |