js多線程的實現-Worker

你們都知道js是基於單線程的,而這個線程就是瀏覽器的js引擎。
首先來看一下你們用的瀏覽器都具備那些線程吧。javascript

若是咱們要執行一些耗時的操做,好比加載一張很大的圖片,咱們可能須要一個進度條來讓用戶進行等待,在等待的過程當中,整個js線程會被阻塞,後面的代碼不能正常運行,這可能大大的下降用戶體驗,這時候咱們就指望擁有一個工做線程來處理這些耗時的操做。在傳統的html時代是基本不可能實現的,而如今,咱們擁有一種叫作worker的東西。它是js裏的一個類,而咱們只須要建立它的實例就可使用它。html

var worker = new Worker(js_file_path);

參數填上你的js文件的路徑,這個js文件將會在瀏覽器新開的線程裏運行,而與原先的js引擎的線程並不影響。java

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>worker</title>
</head>
<body>
    <input type="text" name="ipt" id="ipt" value=""><br>
    <input type="button" name="start" id="start" value="start">
    <input type="button" name="stop" id="stop" value="stop">
    <input type="button" name="alert" id="alert" value="alert">
    <script type="text/javascript">
        var ipt = document.getElementById("ipt");
        var start = document.getElementById("start");
        var stop = document.getElementById("stop");
        var alt = document.getElementById("alert");
        var worker = new Worker("js/test.js");
        function getMessage() {
            worker.onmessage = function() {
                ipt.value = event.data;
            }
        }
        getMessage();
        stop.addEventListener("click", function() {
            //用於關閉worker線程
            worker.terminate();
        })
        start.addEventListener("click", function() {
            //開啓worker線程
            worker = new Worker("js/test.js");
            getMessage();
        })
        alt.addEventListener("click", function() {
            alert("i'm a dialog");
        })
    </script>
</body>
</html>

 

test.js裏的代碼,也就是存在於worker線程裏的代碼web

var i = 0;
function mainFunc(){
    i++;
    //把i發送到瀏覽器的js引擎線程裏
    postMessage(i);
}
var id = setInterval(mainFunc,1000);

運行起來咱們會發現chrome

點擊"alert"裏的「肯定」後,它的數值並不是2,而是一個比2更大的數瀏覽器

雖然dialog的彈出會阻塞js引擎線程,可是並不影響worker線程的運行,因此,在咱們點擊肯定後,只是在js引擎線程上更新了新的內容,而數值是一直在跑動的,這就說明worker線程和本來的js線程互不影響.服務器

那麼既然互不影響,兩個線程之間要怎麼來聯繫呢,答案其實已經在代碼裏了,那就是onPostMessage 和 onmessage這兩個函數,其中onPostMessage(data)的參數是你要傳遞的數據,而onmessage是一個回調函數,只有在接受到數據時,onmessage會被回調,onmessage有一個隱藏的參數,那就是event,咱們能夠用event.data獲取到傳遞過來的數據來更新主線程。函數

使用worker線程應注意的是,全部js裏集成的對象都在js線程裏,而並不是worker線程。
例如咱們在worker線程裏寫上:post

var a = document.getElementById("a");

結果你會獲得一條Error,告訴你找不到document,或者document is undefined。因此咱們儘可能把須要的東西都寫到主線程裏,而只把耗時的操做寫到worker線程裏。spa

注意:若是所運行的html頁面在本地啓動腳本,chrome會報錯。

緣由分析:Chrome從本地文件運行腳本時不容許加載web worker.

解決辦法:啓動web容器,經過服務器訪問頁面資源。好比:localhost:8081/worker.html 或這換種瀏覽器試試。

 

參考: https://www.cnblogs.com/haodawang/articles/5850822.html

相關文章
相關標籤/搜索