1. 程式人生 > 實用技巧 >JavaScript高階(04_執行緒機制和事件機制)

JavaScript高階(04_執行緒機制和事件機制)

執行緒與程序

  • 程序:

    • 程式的一次執行, 它佔有一片獨有的記憶體空間

    • 可以通過windows工作管理員檢視程序

  • 執行緒:

    • 是程序內的一個獨立執行單元

    • 是程式執行的一個完整流程

    • 是CPU的最小的排程單元

  • 關係

    • 一個程序至少有一個執行緒(主)

    • 程式是在某個程序中的某個執行緒執行的

瀏覽器核心模組組成

  • 主執行緒

    • js引擎模組 : 負責js程式的編譯與執行

    • html,css文件解析模組 : 負責頁面文字的解析

    • DOM/CSS模組 : 負責dom/css在記憶體中的相關處理

    • 佈局和渲染模組 : 負責頁面的佈局和效果的繪製(記憶體中的物件)

  • 分執行緒

    • 定時器模組 : 負責定時器的管理

    • DOM事件模組 : 負責事件的管理

    • 網路請求模組 : 負責Ajax請求

js執行緒

  • js是單執行緒執行的(回撥函式也是在主執行緒)

  • H5提出了實現多執行緒的方案: Web Workers

  • 只能是主執行緒更新介面

定時器問題:

  • 定時器並不真正完全定時

  • 如果在主執行緒執行了一個長時間的操作, 可能導致延時才處理

事件處理機制(圖)

  • 程式碼分類

    • 初始化執行程式碼: 包含繫結dom事件監聽, 設定定時器, 傳送ajax請求的程式碼

    • 回撥執行程式碼: 處理回撥邏輯

  • js引擎執行程式碼的基本流程:

    • 初始化程式碼===>回撥程式碼

  • 模型的2個重要組成部分:

    • 事件管理模組

    • 回撥佇列

  • 模型的運轉流程

    • 執行初始化程式碼, 將事件回撥函式交給對應模組管理

    • 當事件發生時, 管理模組會將回調函式及其資料新增到回撥列隊中

    • 只有當初始化程式碼執行完後(可能要一定時間), 才會遍歷讀取回調佇列中的回撥函式執行

H5 Web Workers

  • 可以讓js在分執行緒執行

  • Worker

    var worker = new Worker('worker.js');
    worker.onMessage = function(event){event.data} : 用來接收另一個執行緒傳送過來的資料的回撥
    worker.postMessage(data1) : 向另一個執行緒傳送資料
  • 問題:

    • worker內程式碼不能操作DOM更新UI

    • 不是每個瀏覽器都支援這個新特性

    • 不能跨域載入JS

  • svn版本控制

  • svn server

分號問題

  1. 一條js語句的後面可以不加分號

  2. 在下面2種情況下不加分號會有問題

    • 小括號開頭的前一條語句

    • 中方括號開頭的前一條語句

    • 解決辦法: 在行首加分號

記憶體溢位與記憶體洩露

  1. 記憶體溢位

    • 一種程式執行出現的錯誤

    • 當程式執行需要的記憶體超過了剩餘的記憶體時, 就出丟擲記憶體溢位的錯誤

    var obj = {}
      for (var i = 0; i < 10000; i++) {
        obj[i] = new Array(10000000)
        console.log('-----')
    }
  2. 記憶體洩露

    • 佔用的記憶體沒有及時釋放

    • 記憶體洩露積累多了就容易導致記憶體溢位

    • 常見的記憶體洩露:

      • 意外的全域性變數

        function fn() {
          a = new Array(10000000)
          console.log(a)
        }
        fn()
      • 沒有及時清理的計時器或回撥函式

        var intervalId = setInterval(function () { //啟動迴圈定時器後不清理
            console.log('----')
          }, 1000)
        //clearInterval(intervalId) //解決方法
      • 閉包

        function fn1() {
          var a = 4
          function fn2() {
            console.log(++a)
          }
          return fn2
        }
        var f = fn1()
        f()
        ​
        // f = null //解決方法