欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js多線程解決方案Web?Worker簡單說明與實例演示

 更新時間:2023年02月18日 14:14:09   作者:前端人  
這篇文章主要介紹了js多線程解決方案Web?Worker,他是HTML5提供的一個JavaScript多線程解決方案,我們可以將一些大計算量的代碼交由web Worker運行而不凍結(jié)用戶界面

一、什么是Web Worker ?

JavaScript 語言是采用單線程模型,也就是任務(wù)只能在一個線程上完成,一次只能做一件事,前面任務(wù)沒執(zhí)行完,后面的任務(wù)只能排隊等待,由于多核 CPU 的出現(xiàn),單線程帶來很大不便,無法充分發(fā)揮計算機的能力。

Web Worker 就是為了 javascript 創(chuàng)造多線程而生的,主線程創(chuàng)建 worker 子線程,將一些任務(wù)分配給后臺運行,等到子線程完成計算任務(wù),再把結(jié)果返回給主線程,好處是計算密集型或高延遲的任務(wù)被 worker 負擔了,主線程就會很流暢。網(wǎng)頁加載展示可分為兩部分:主進程也叫 UI 進程,子進程也叫工作進程,子進程不能控制 UI 進程,只能進行數(shù)據(jù)交互。

Web Worker 子線程一旦創(chuàng)建成功,就會獨立于其他腳本始終運行,不會被主線程上活動打斷。這樣有利于隨時響應(yīng)主線程的通信。但是這也造成 Worker 比較耗費資源,不應(yīng)該過度使用,使用完畢之后應(yīng)該關(guān)閉。

使用 Web Worker 注意點:

  • 同源限制:分配給 Worker 線程運行的腳本,必須與主線程的腳本文件同源,否則存在跨域問題。
  • DOM限制:Worker 線程所在的全局對象,與主線程不同,無法讀取主線程的DOM對象,也無法使用 window、document、parent 這些對象。但是Worker線程可以使用navigation和location對象。
  • 數(shù)據(jù)通信:Worker 線程與主線程不在一個環(huán)境,不能直接通信,必須通過消息來完成數(shù)據(jù)通信。
  • 腳本限制:Worker 線程不能執(zhí)行 window 的 alert、confirm 方法。但是可以通過ajax發(fā)送請求。
  • 文件限制:Worker線程無法讀取本地文件,子線程加載的腳本必須來自網(wǎng)絡(luò)。

相關(guān)API

1.Worker:構(gòu)造函數(shù),加載分線程執(zhí)行的js文件
2.Worker.prototype.onmessage:用于接受另一個線程的回調(diào)函數(shù)
3.WorKer.prototype.postMessage:向另一個線程發(fā)送消息

**不足**
worker內(nèi)代碼不能操作DOM
不能跨域加載JS
不是每個瀏覽器都支持這個新特性

var input = document.getElementById('number')
function computed(n){
    return n<=2 ? 1:computed(n-1) + computed(n-2) //遞歸調(diào)用
}
document.getElementById('btn').onclick = function(){
    var number = input.value
    var result = computed(number)
    alert(result)
}

上面代碼當按鈕被點擊時根據(jù)用戶輸入的值進行斐波拉契數(shù)列的計算
當這個值較大時,由于遞歸導致頁面要很長時間才能響應(yīng),在等待響應(yīng)的過程中由于js的單線程機制導致我們不能進行任何操作,頁面就像被卡死了一樣,如果要解決這個問題,可以用 web Wokers實現(xiàn)
將計算的邏輯交給分線程執(zhí)行,這樣在計算的過程中我們可以正常操作頁面

//index.html
 var input = document.getElementById('number')
        
        document.getElementById('btn').onclick = function(){
            var number = input.value
            //創(chuàng)建一個worker對象
            var worker = new Worker('./js/worker.js')
            console.log(worker)
            //向分線程發(fā)送消息
            worker.postMessage(number)
            console.log('主線程向分線程發(fā)送數(shù)據(jù):'+number)
            //綁定接受消息的監(jiān)聽
            worker.onmessage = function(event){
                console.log('主線程接受分線程返回的數(shù)據(jù):'+event.data)
            }
        }
//worker.js
function computed(n){
    return n<=2 ? 1:computed(n-1) + computed(n-2) //遞歸調(diào)用
}

var onmessage = function(event){
    var number = event.data
    console.log('分線程接受主線程發(fā)送的數(shù)據(jù):'+number)
    //計算
    var result = computed(number)
    postMessage(result)
    console.log('分線程向主線程返回數(shù)據(jù):'+number)
}

二、使用語法

2.1 創(chuàng)建Worker線程:

創(chuàng)建worker之前,先檢查瀏覽器是否支持它。使用 typeof 檢查,代碼如下:

if( typeof Worker !== undefined ){
 console.log("支持Worker線程")
}else{
 console.log("不支持Worker")
}

檢查瀏覽器支持 worker 之后,主線程使用 new 命令,調(diào)用 worker() 構(gòu)造函數(shù),新建 Worker 線程。

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

構(gòu)造函數(shù)的參數(shù)是一個腳本文件,該文件不能是本地文件,必須來自網(wǎng)絡(luò)腳本,該文件就是Worker 線程要執(zhí)行的任務(wù)。如果該文件加載失敗,Worker 就會失敗。

2.2 主線程與子線程數(shù)據(jù)通信:

主線程調(diào)用 postMessage() 方法,向 Worker 發(fā)消息。postMessage(參數(shù)) 方法中參數(shù)就是傳給 Worker 的數(shù)據(jù),這個數(shù)據(jù)可以是任意格式。

myWorker.postMessage("你好")

緊接著 Worker 線程,通過 onmessage 指定監(jiān)聽函數(shù),接收消息。worker.js 代碼如下:

this.onmessage = function(res){
 console.log("接收到消息",res.data)
 this.postMessage("我收到消息了")
}

worker子進程收到消息之后,可以繼續(xù)向主進程發(fā)送消息,使用 postMessage()。代碼如上。

主進程也通過onmessage監(jiān)聽函數(shù)接收消息。

myWorker.onmessage = function(res){
 console.log("主線程收到消息:",res.data)
}

2.3 Worker線程

Worker線程內(nèi)部,添加 this.onmessage 監(jiān)聽函數(shù),其中 this 是子線程的全局對象,也可以替換成 self,self 代表子線程本身。等同于:

self.onmessage    《=》 this.onmessage

除了使用 self.onmessage 指定監(jiān)聽函數(shù),也可以使用 this.addEventListener() 監(jiān)聽事件對象。上述 worker.js 代碼可改為:

//寫法一
this.addEventListener("message",function(res){
 console.log("res",res.data)
})
//寫法二
addEventListener("message",function(res){
 this.console.log("1",res.data)
})

2.4 錯誤處理

主線程可以監(jiān)聽Worker是否發(fā)生錯誤,如果發(fā)生錯誤,Worker 會觸發(fā)主線程的 error 事件。

// 寫法一
myWorker.onerror = function(e){
 console.log('e',e)
}
//寫法二
myWorker.addEventListener("error",function(e){
 console.log("e",e)
})

worker 子線程也可以監(jiān)聽 error 事件。

2.5 關(guān)閉 Worker

Worker 比較耗費資源,不應(yīng)該過度使用,使用完畢之后應(yīng)該關(guān)閉。主線程和子線程都可以關(guān)閉。

//主線程關(guān)閉
myWorker.terminate() 
 
//子線程關(guān)閉
self.close() //方法一
this.close() //方法二

三、同一個網(wǎng)頁的Web Worker

通常情況下,Worker 載入的是一個單獨的 javascript 文件,但是也可以載入與主線程在同一個網(wǎng)頁的代碼。網(wǎng)頁中添加 Worker 腳本,必須注意指定script標簽的type屬性是一個瀏覽器不認識的值,否則就會失去意義。如:

<script type="app/worker" id="wrs">
 this.onmessage = function(res){
  console.log("接收參數(shù)",res.data)
 }
</script>

然后,需要讀取這段代碼,先將嵌入網(wǎng)頁的腳本代碼轉(zhuǎn)成二進制對象,然后為這個二進制對象生成url,再讓worker加載url,這樣就實現(xiàn)了主進程和worker在同一個網(wǎng)頁內(nèi)。代碼如下:

<script>
 var blob = new Blob([document.querySelector("#wrs").textContent]);
 var url = window.URL.createObjectURL(blob);
 var worker = new Worker(url)
 worker.postMessage("發(fā)送數(shù)據(jù)")
</script>

四、Worker 屬性和方法總結(jié)

Worker構(gòu)造函數(shù)方法:

  • Worker.postMessage() - 發(fā)送消息。
  • Worker.onmessage() - 監(jiān)聽子線程發(fā)送過來的數(shù)據(jù)。
  • Worker.onmessageerror() - 發(fā)送數(shù)據(jù)無法序列化時觸發(fā)事件。
  • Worker.onerror() - 錯誤處理。
  • Worker.terminate() - 結(jié)束Worker。

子進程屬性方法:

Worker() 構(gòu)造函數(shù),可以接受兩個參數(shù),第一個是腳本的地址,第二個是參數(shù)是配置對象,該對象指定Worker的名稱。如:

var myWorker = new Worker('worker.js', { name : 'myWorker' });
  • self.name - Worker 的名字
  • self.onmessage - 接收消息
  • self.postmessage - 發(fā)送數(shù)據(jù)
  • self.onerror - 錯誤處理
  • self.onmessageerror - 發(fā)送的數(shù)據(jù)無法序列化成字符串時觸發(fā)事件
  • self.close - 關(guān)閉Worker線程
  • self.importScript() - 加載js腳本

以上就是js多線程解決方案Web Workers簡單說明與實例演示的詳細內(nèi)容,更多關(guān)于js多線程解決方案Web Workers說明的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 了解JavaScript中l(wèi)et語句

    了解JavaScript中l(wèi)et語句

    使用let語句,允許你在JavaScript中創(chuàng)建塊范圍局部變量。let語句是在JavaScript的ECMAScript 6標準中引入的。下面我們來簡單學習一下吧
    2019-05-05
  • JavaScript中的getDay()方法使用詳解

    JavaScript中的getDay()方法使用詳解

    這篇文章主要介紹了JavaScript中的getDay()方法使用詳解,是JS入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript數(shù)據(jù)類型詳解

    JavaScript數(shù)據(jù)類型詳解

    這篇文章主要介紹了JavaScript數(shù)據(jù)類型詳解,本文詳細講解了JavaScript中有5種基本數(shù)據(jù)類型:Undefined、Null、Boolean、Number和String,需要的朋友可以參考下
    2015-04-04
  • easyui validatebox驗證

    easyui validatebox驗證

    這篇文章主要介紹了easyui validatebox驗證,需要的朋友可以參考下
    2016-04-04
  • JavaScript中的eval()函數(shù)詳解

    JavaScript中的eval()函數(shù)詳解

    和其他很多解釋性語言一樣,JavaScript同樣可以解釋運行由JavaScript源代碼組成的字符串,并產(chǎn)生一個值。JavaScript通過全局函數(shù)eval()來完成這個工作
    2013-08-08
  • JavaScript入門教程(4) js瀏覽器對象

    JavaScript入門教程(4) js瀏覽器對象

    navigator 瀏覽器對象,包含了正在使用的 Navigator 的版本信息。反映了當前使用的瀏覽器的資料。JavaScript 客戶端運行時刻引擎自動創(chuàng)建 navigator 對象。
    2009-01-01
  • Javascript核心讀書有感之類型、值和變量

    Javascript核心讀書有感之類型、值和變量

    這篇文章主要介紹了Javascript核心讀書有感之類型、值和變量,需要的朋友可以參考下
    2015-02-02
  • 2019年度web前端面試題總結(jié)(主要為Vue面試題)

    2019年度web前端面試題總結(jié)(主要為Vue面試題)

    轉(zhuǎn)眼2019又要過去了,作為一名前端碼農(nóng),又熬過一個沒日沒夜的年頭,頭發(fā)又少了不少,去年的學習計劃一半也沒完成,唉。。。 現(xiàn)在為大家總結(jié)一下這一年面試的幾家公司的關(guān)于前端面試題吧
    2020-01-01
  • 詳解JavaScript中的自定義事件編寫

    詳解JavaScript中的自定義事件編寫

    這篇文章主要介紹了JavaScript中的自定義事件編寫,自定義事件是在瀏覽器中編寫Web頁面操作功能的基本方式,需要的朋友可以參考下
    2016-05-05
  • 做網(wǎng)頁的一些技巧(續(xù))

    做網(wǎng)頁的一些技巧(續(xù))

    做網(wǎng)頁的一些技巧(續(xù))...
    2007-02-02

最新評論