介紹
Web Workers 是HTML5提供的一個(gè)javaScript多線程解決方案。我們可以將一些大計(jì)算量的代碼交給Web Workers運(yùn)行而不凍結(jié)用戶界面。但是子線程完全受主線程控制,且不得操作DOM。所以,這個(gè)新標(biāo)準(zhǔn)并沒有改變javaScript單線程的本質(zhì)。

image.png
使用
背景:假設(shè)頁(yè)面中有一個(gè)輸入框,根據(jù)用戶輸入數(shù)值,來計(jì)算相應(yīng)的斐波那契數(shù)列的結(jié)果。當(dāng)輸入的值比較大的時(shí)候,計(jì)算需要的時(shí)間非常長(zhǎng),而且頁(yè)面被凍結(jié)不能進(jìn)行其他操作。這時(shí)候我們希望能把計(jì)算放到分線程去執(zhí)行,不影響主線程頁(yè)面操作。
<!DOCTYPE html>
<html lang="en">
<body>
<input type="text" placeholder="請(qǐng)輸入數(shù)值" id="number" />
<button id="btn">計(jì)算</button>
<script>
var input = document.getElementById('number')
document.getElementById('btn').onclick = function() {
var number = input.value
// 創(chuàng)建一個(gè)worker對(duì)象
var worker = new Worker('worker.js') // 接收一個(gè)分線程文件地址
// 綁定接收消息的監(jiān)聽
worker.onmessage = function(event) {
// 通過event.data接收數(shù)據(jù)
console.log('主線程接收分線程返回的數(shù)據(jù):' + event.data)
alert(event.data)
}
// 向分線程發(fā)送消息
worker.postMessage(number)
console.log('主線程向分線程發(fā)送數(shù)據(jù):' + number)
}
</script>
</body>
</html>
寫一個(gè)分線程js文件,把大量計(jì)算的邏輯寫到這里
// worker.js
function fibonacci(n) {
return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
}
// 固定寫法
var onmessage = function(event) {
var number = event.data
console.log('分線程接收到主線程發(fā)送的數(shù)據(jù):' + number)
// 計(jì)算
var result = fibonacci(number)
postMessage(result)
console.log('分線程向主線程返回?cái)?shù)據(jù):' + result)
// alert(result) alert是window的方法,在分線程不能調(diào)用
// 分線程中的全局對(duì)象不再是window, 所以在分線程中不可能更新界面
}

image.png
分線程中的this不再是window,而是下面的這個(gè)對(duì)象,所以分線程中不能操作頁(yè)面。

image.png
Web Workers的局限
- 同源限制(不支持跨域)
分配給 Worker 線程運(yùn)行的腳本文件,必須與主線程的腳本文件同源。 - DOM 限制(不能訪問DOM)
Worker 線程所在的全局對(duì)象,與主線程不一樣,無法讀取主線程所在網(wǎng)頁(yè)的 DOM 對(duì)象,也無法使用document、window、parent這些對(duì)象。但是,Worker 線程可以使用navigator對(duì)象和location對(duì)象。 - 通信聯(lián)系
Worker 線程和主線程不在同一個(gè)上下文環(huán)境,它們不能直接通信,必須通過消息Worker.postMessage()完成。 - 腳本限制
Worker 線程不能執(zhí)行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 對(duì)象發(fā)出 AJAX 請(qǐng)求。 - 文件限制
Worker 線程無法讀取本地文件,即不能打開本機(jī)的文件系統(tǒng)(file://),它所加載的腳本,必須來自網(wǎng)絡(luò)。
注意點(diǎn)
-
Worker 線程無法讀取本地文件
直接在瀏覽器打開html文件會(huì)出現(xiàn)下面的報(bào)錯(cuò):
image.png
可以用webpack等開啟一個(gè)本地服務(wù)器,然后在瀏覽器上訪問。
