js多線程(worker)


    瀏覽器端js是單線程執行,所以當js執行高負載運算時,UI渲染就會阻塞,頁面就會出現卡頓,用戶體驗就不是很好

    js為此也提供了異步操作,例如: 定時器(setTimeout 和 setInterval),Ajax請求等,但異步終究還是單線程,不能從根本上解決問題,像setTimeout並不能拿到正確的值,因為執行的時候將該任務放到主線程執行,只有當前面的任務執行完才開始執行,所以即使設置時間為0,也並不一定立刻執行

   所以HTML5標准添加了Web Worker,worker允許一段js程序運行在主線程之外的線程,子線程與主線程互不干擾,當子線程的代碼執行完成,將結果返回給主線程,主線程接收到相應結果后再做對應處理,當有一些計算密集型或高延遲的任務就可以交給worker子線程來負擔,主線程就不會阻塞

   worker是window對象的一個方法,一個worker對象可通過構造函數(window.worker())來創建,創建對象時,需要傳給構造函數一個js文件,該文件包含了放到子線程中運行的代碼

   worker通過postMessage()和onmessage = () => {} 來進行通信,主線程和子線程通信是雙向的,都有可以發送和接收信息,postMessage傳遞的數據都是拷貝傳遞(ArrayBuffer除外)

   子線程運行耗損系統資源,所以當執行完畢后,我們可以手動關閉子線程

    在主線程中關閉: worker.terminate()

    在子線程中關閉: self.close()  (在子線程中window需改寫成self,下文有解釋)

   

     worker限制

     1)同源

        分配給worker子線程運行的腳本文件,必須與主線程的腳本文件同源,包括協議,域名和端口,不支持本地地址(file://);

        當使用CDN來存儲js文件時,主線程與子線程就會出現跨域

        解決方法: 【1】將子線程的腳本轉換成Blod對象

                        【2】然后給Blod對象創建一個URL

                        【3】將這個URL傳給worker的構造函數

       示例代碼: 

          var workerBlob = new Blob(['(' + function +')()'], { type: "text/javascript" });

          var url = window.URL.createObjectURL(workerBlob);

          var worker = new Worker(url);

    2) 訪問 

        worker子線程所在的全局對象,與主線程不在一個上下文環境,所以無法讀取主線程所在網頁的DOM,無法使用document,window,parent這些對象,global指向有變更,window需要改寫成self,不能執行alert()和comfire()的方法,只能讀取部分navigator對象內的數據

   3)使用異步

        worker子線程中支持js的異步操作,但仍然不可以跨域

 

    worker的兼容性還不錯,但不兼容IE9

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM