• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. 淺談javascript中的單線程理解

        時間:2024-08-16 20:41:27 JavaScript 我要投稿
        • 相關推薦

        淺談javascript中的單線程理解

          一、JavaScript 引擎是單線程的

          可以從下面的代碼中看到,第一個用setTimeout中的代碼是死循環,由于是單線程,下面的兩個定時器就沒機會執行了。

          瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現3個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。

          JavaScript引擎是基于事件驅動單線程執行的,JS引擎一直等待著任務隊列中任務的到來然后加以處理,瀏覽器無論再什么時候都只有一個JS線程在運行JS程序。

          GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行。但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。

          瀏覽器事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其他線程如鼠標點擊、AJAX異步請求等,但由于JS的單線程關系所有這些事件都得排隊等待JS引擎處理。

          由上圖可看出,瀏覽器中的JavaScript引擎是基于事件驅動的,這里的事件可看作是瀏覽器派給它的各種任務,JavaScript引擎一直等待著任務隊列中任務的到來,由于單線程關系,這些任務得進行排隊,一個接著一個被引擎處理。

          t1、t2....tn表示不同的時間點,tn下面對應的小方塊代表該時間點的任務。

          t1時刻:

          1、GUI渲染線程

          2、瀏覽器事件觸發線程:

          在t1時間段內,首先是用戶點擊了一個鼠標鍵,點擊被瀏覽器事件觸發線程捕捉后形成一個鼠標點擊事件,由圖可知,對于JavaScript引擎線程來說,這事件是由其它線程異步傳到任務隊列尾的,由于引擎正在處理t1時的任務,這個鼠標點擊事件正在等待處理。

          3、定時觸發線程:

          這里的瀏覽器模型定時計數器并不是由JavaScript引擎計數的,因為JavaScript引擎是單線程的,如果處于阻塞線程狀態就計不了時,它必須依賴外部來計時并觸發定時,所以隊列中的定時事件是異步事件。

          4、在這t1的時間段內,繼鼠標點擊事件觸發后,先前已設置的setTimeout定時也到達了,此刻對JavaScript引擎來說,定時觸發線程產生了一個異步定時事件并放到任務隊列中,該事件被排到點擊事件回調之后,等待處理。同理,還是在t1時間段內,接下來某個setInterval定時器也被添加了,由于是間隔定時,在t1段內連續被觸發了兩次,這兩個事件被排到隊尾等待處理。

          5、ajax異步請求:

          瀏覽器新開一個http線程請求,當請求的狀態變更時,如果先前已設置回調,這異步線程就產生狀態變更事件放到JavaScript引擎的處理隊列中等待處理。

          二、任務的執行順序不同,顯示結果也不同

          1)未使用setTimeout函數

          在網上找到的一段代碼實例,這里用來演示一下。

          do something

          我在firefox中執行了上面的代碼。計劃是點擊“do something”按鈕,然后顯示“doing...please wait...”,接著執行sleep,最后顯示“done”。

          但是結果是點擊后,瀏覽器卡住3秒左右,最后直接顯示done。

          分析下看出,在做status.innerHTML設置的時候,是需要執行GUI渲染線程的,但是現在還在執行JavaScript引擎線程,而JavaScript引擎線程與GUI渲染線程是互斥的,所以就最后顯示了done。

          2)使用了setTimeout函數

          do something timer

          在“doing...please wait...”后面加了個setTimeout,延時執行,給了瀏覽器渲染的時間,這個時候會顯示出“doing...please wait...”的字樣,然后執行sleep函數,最后顯示“done”。

          后面有網友發現在firefox中不起作用,的確有這個問題,后面我修改了一下代碼,將局部變量的聲明,onclick的綁定放到了window.onload事件中,等頁面結構加載完成后,我再做腳本操作。

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【淺談javascript中的單線程理解】相關文章:

        對javascript的理解03-29

        javascript面向對象中的對象怎么理解03-30

        有關深入理解JavaScript中的并行處理的介紹03-30

        理解JavaScript原型鏈教程03-30

        淺談如何深入學習Javascript中的this關鍵字04-02

        javascript的閉包概念怎么理解03-29

        在Java中執行JavaScript代碼04-01

        Javascript中typeof 用法歸納04-01

        JavaScript中的with關鍵字03-25

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 亚洲第一高清尤物在线播放 | 一本清视频在线观看 | 亚洲最大AV资源网在线观看 | 一级特黄日本少妇 | 亚洲一级人成字幕 | 日本a∨免费一区二区三区 亚洲国产天堂网精品网站 日本高清中文字幕视频在线 |

            淺談javascript中的單線程理解

              一、JavaScript 引擎是單線程的

              可以從下面的代碼中看到,第一個用setTimeout中的代碼是死循環,由于是單線程,下面的兩個定時器就沒機會執行了。

              瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現3個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。

              JavaScript引擎是基于事件驅動單線程執行的,JS引擎一直等待著任務隊列中任務的到來然后加以處理,瀏覽器無論再什么時候都只有一個JS線程在運行JS程序。

              GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行。但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。

              瀏覽器事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其他線程如鼠標點擊、AJAX異步請求等,但由于JS的單線程關系所有這些事件都得排隊等待JS引擎處理。

              由上圖可看出,瀏覽器中的JavaScript引擎是基于事件驅動的,這里的事件可看作是瀏覽器派給它的各種任務,JavaScript引擎一直等待著任務隊列中任務的到來,由于單線程關系,這些任務得進行排隊,一個接著一個被引擎處理。

              t1、t2....tn表示不同的時間點,tn下面對應的小方塊代表該時間點的任務。

              t1時刻:

              1、GUI渲染線程

              2、瀏覽器事件觸發線程:

              在t1時間段內,首先是用戶點擊了一個鼠標鍵,點擊被瀏覽器事件觸發線程捕捉后形成一個鼠標點擊事件,由圖可知,對于JavaScript引擎線程來說,這事件是由其它線程異步傳到任務隊列尾的,由于引擎正在處理t1時的任務,這個鼠標點擊事件正在等待處理。

              3、定時觸發線程:

              這里的瀏覽器模型定時計數器并不是由JavaScript引擎計數的,因為JavaScript引擎是單線程的,如果處于阻塞線程狀態就計不了時,它必須依賴外部來計時并觸發定時,所以隊列中的定時事件是異步事件。

              4、在這t1的時間段內,繼鼠標點擊事件觸發后,先前已設置的setTimeout定時也到達了,此刻對JavaScript引擎來說,定時觸發線程產生了一個異步定時事件并放到任務隊列中,該事件被排到點擊事件回調之后,等待處理。同理,還是在t1時間段內,接下來某個setInterval定時器也被添加了,由于是間隔定時,在t1段內連續被觸發了兩次,這兩個事件被排到隊尾等待處理。

              5、ajax異步請求:

              瀏覽器新開一個http線程請求,當請求的狀態變更時,如果先前已設置回調,這異步線程就產生狀態變更事件放到JavaScript引擎的處理隊列中等待處理。

              二、任務的執行順序不同,顯示結果也不同

              1)未使用setTimeout函數

              在網上找到的一段代碼實例,這里用來演示一下。

              do something

              我在firefox中執行了上面的代碼。計劃是點擊“do something”按鈕,然后顯示“doing...please wait...”,接著執行sleep,最后顯示“done”。

              但是結果是點擊后,瀏覽器卡住3秒左右,最后直接顯示done。

              分析下看出,在做status.innerHTML設置的時候,是需要執行GUI渲染線程的,但是現在還在執行JavaScript引擎線程,而JavaScript引擎線程與GUI渲染線程是互斥的,所以就最后顯示了done。

              2)使用了setTimeout函數

              do something timer

              在“doing...please wait...”后面加了個setTimeout,延時執行,給了瀏覽器渲染的時間,這個時候會顯示出“doing...please wait...”的字樣,然后執行sleep函數,最后顯示“done”。

              后面有網友發現在firefox中不起作用,的確有這個問題,后面我修改了一下代碼,將局部變量的聲明,onclick的綁定放到了window.onload事件中,等頁面結構加載完成后,我再做腳本操作。