web worker 簡介

web worker 簡介

一般,瀏覽器執行某段程序的時候會阻塞直到運行結束後在恢復到正常狀態,而HTML5的Web Worker就是爲了解決這個問題。經過worker線程完成密集計算,避免程序的阻塞和頁面的卡頓(fps太低)html

示例

用fibonacci數列來模擬測試web

worker-test.htmlajax

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>測試 web worker</title>
</head>

<body>
    <script>
        function fibonacci(n) {
            return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2);
        }


        function testNoWorker() {
            let start = Date.now();
            fibonacci(38);
            let end = Date.now();
            console.log(end - start); // wait a long time..
        }

        function testUseWorker() {
            let start = Date.now();
            let worker = new Worker('worker.js');
            worker.postMessage(38);
            worker.addEventListener('message', function (event) {
                let end = Date.now();
                console.log('worker result: ', end -start);
            });
            console.log('can do other jobs, when worker is computing');
        }

        testNoWorker();
        testUseWorker();
    </script>
</body>

</html>

worker.jsjson

function fibonacci(n) {
    return n < 2 ? n : arguments.callee(n-1) + arguments.callee(n-2);
}

self.addEventListener('message', function (event) {
    let result = fibonacci(event.data);
    self.postMessage(result);
});



// 可用 setTimeout , setInterval
setTimeout(() => {
    console.log('timeout..');
}, 100);

setInterval(() => {
    console.log('setInterval...');
}, 200);

// 可發起ajax
fetch('data.json').then(res => res.json()).then(data => {console.log(data, '<--json data')});

// 可訪問 location, navigator
console.log(location);
console.log(navigator);

// worker.js的執行上下文爲 self (worker實例), 
// self上的屬性和方法可直接調用
console.log(typeof addEventListener);
console.log(typeof postMessage);

假設主頁面須要屢次執行耗時的操做(如: fibonacci), 可以下用worker來異步執行.跨域

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>測試 實例化多個 web worker</title>
</head>

<body>
    <script>
        function fibonacci(n) {
            let start = Date.now();
            let worker = new Worker('worker.js');

            worker.addEventListener('message', function (event) {
                let end = Date.now();
                console.log('worker result: ', end - start);
            });
            worker.postMessage(n);
        }

        /* 同時跑多個worker, 會下降每一個worker線程的性能;但總比阻塞頁面要好 */
        fibonacci(38);
        console.log('after one');
        
        fibonacci(38);
        console.log('after two');
        
        fibonacci(38);
        console.log('after three');

        console.log('can handle other jobs..');


    </script>
</body>

</html>

跨域與腳本引入

在主頁面實例化worker, new Worker('/url/to/worker.js') worker腳本必須和主頁面同域;在worker腳本中,能夠 self.importScripts('url/to/script.js') 導入任何域的腳本, 多個 self.importScripts() 是順序同步加載的瀏覽器

worker的方法

  • worker.terminate() 終止worker線程

限制

  • 不能訪問主頁面的全局變量和函數,沒有 window, document; 但可訪問 location, navigator
  • 支持setTimeout, setInterval, 可發起ajax
  • worker不能訪問和操做dom
  • postMessage傳的數據都會被複制,不會指向同一個內存地址
相關文章
相關標籤/搜索