HTML學習筆記(八) Web Worker

Web Worker 爲 JavaScript 創建多線程環境

主線程可以創建 Worker 線程,並將一些高延遲的任務分配給 Worker 線程在後臺運行

而主線程只會負責渲染和交互,從而保證頁面的流暢性

Web Worker 有兩種類型,分別是 Dedicated Web Worker 和 Shared Web Worker

  • Dedicated Web Worker:只有一個頁面可以使用這個 Web Worker
  • Shared Web Worker:多個同源頁面可以共享一個 Web Worker,爲跨頁面通信提供一種解決方案

下面介紹 Dedicated Web Worker

主線程通過構造函數 Worker(),創建一個 Worker 線程,並在參數中指定需要執行的腳本文件

var worker = new Worker('worker.js')

構造函數返回一個 Worker 對象,便於主線程與 Worker 線程通信,Worker 對象常用的屬性和方法如下:

  • onerror:用於指定 error 事件的監聽函數,當 Worker 發生錯誤時觸發
  • onmessage:用於指定 message 事件的監聽函數,當接收到傳遞的數據時觸發
  • onmessageerror:用於指定 messageerror 事件的監聽函數,當收到的數據無法進行反序列化時觸發
  • postMessage():傳遞數據給 Worker 線程
  • terminate():終止 Worker 線程
<!DOCTYPE html>
<html>
<head>
    <script>
        var worker;

        function submit() {
            if (typeof(Worker) === 'undefined') {
                return
            }
            if (typeof(worker) === "undefined") {
                worker = new Worker('worker.js')
            }
            let input = document.getElementById('data').value
            worker.postMessage(input)
            worker.onmessage = function(event) {
                let result = event.data
                document.getElementById('result').innerText = result
                worker.terminate()
                worker = undefined
            }
            worker.onerror = function(event) {
                console.log('出錯的信息', event.message)
                console.log('出錯的文件', event.filename)
                console.log('出錯的行數', event.lineno)
                console.log('出錯的列數', event.colno)
                worker.terminate()
                worker = undefined
            }
        }
    </script>
</head>
<body>
    <input type="text" id="data" name="data" placeholder="Please Enter Something">
    <button onclick="submit()">Reverse String</button>
    <span id="result"></span>
</body>
</html>

Worker 線程有一個自己的全局對象,selfthis 都提供對該對象的引用,這個對象常用的屬性和方法如下:

  • onmessage:用於指定 message 事件的監聽函數,當接收到傳遞的數據時觸發
  • onmessageerror:用於指定 messageerror 事件的監聽函數,當收到的數據無法進行反序列化時觸發
  • importScripts():用於加載其它腳本
  • postMessage():傳遞數據給主線程
  • close():關閉 Worker 線程
// worker.js

this.onmessage = function(event) {
    let data = event.data
    let result = reverse(data)
    this.postMessage(result)
    this.close()
}

function reverse(content) {
    return content.split('').reverse().join('')
}

使用 Web Worker 需要注意以下的點:

  • 主線程分配給 Worker 線程的腳本文件,不能從本地讀取,它必須來自網絡

  • 主線程分配給 Worker 線程的腳本文件,必須與主線程的腳本文件同源,準確來說應該是與頁面文檔同源

  • Worker 線程不能訪問 window、document、parent 對象,但是可以使用 navigator、location 對象

  • Worker 線程不能使用 alert、confirm,但是可以使用 setTimeout、setInterval、XMLHttpRequest

  • 主線程和 Worker 線程不能直接通信,必須通過消息傳遞,消息傳遞有兩種方式,一種是拷貝,一種是轉讓

    拷貝:拷貝原始數據,產生一份副本,將副本傳遞給目標線程,這種方法在傳遞較大的數據時比較消耗性能

    轉讓:將原始數據的所有權轉讓給目標線程,原來線程不再具有這個數據

    在默認的實現中,除 ArrayBuffer 外都是拷貝傳遞

【 閱讀更多 HTML 系列文章,請看 HTML學習筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章