前言
在进行计算密集的应用时,单线程的JS中可能会产生卡顿,简单点可以通过添加iframe加载同域页面创建新的进程执行运算,但是这样一方面运维难度较大,并且进程的创建和销毁难度比线程的创建和销毁难度大得多。
HTML5引入了多线程运行模型——Web Worker。
Web Worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 Web Worker 在后台运行。
创建Web Worker文件
在这里,我们创建了计数脚本。该脚本存储于 "demo_workers.js" 文件中:
var i=0;
function timedCount()
{
i=i+1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
postMessage() 方法 - 它用于向 HTML 页面传回一段消息。
(Web Worker一般不用于如此简单的脚本,他用于更加消耗CPU资源的任务)
创建Web Worker对象
如果不存在worker对象,则创建一个新的对象。
if(typeof(w)=="undefined")
{
w=new Worker("demo_workers.js");
}
然后就可以通过web worker接收消息了。
向 web worker 添加一个 "onmessage" 事件监听器(或者addeventListener('message')):
w.onmessage=function(event){
document.getElementById("result").innerHTML=event.data; // postMessage的消息
};
终止Web Worker
w.terminate();
题外话:postMessage
postMessage() 方法用于安全地实现跨源通信。
发送程序:
<div>
<input id="text" type="text" value="Runoob" />
<button id="sendMessage" >发送消息</button>
</div>
<iframe loading="lazy" id="receiver" src="https://c.runoob.com/runoobtest/postMessage_receiver.html" width="300" height="360">
<p>你的浏览器不支持 iframe。</p>
</iframe>
<script>
window.onload = function() {
var receiver = document.getElementById('receiver').contentWindow;
var btn = document.getElementById('sendMessage');
btn.addEventListener('click', function (e) {
e.preventDefault();
var val = document.getElementById('text').value;
receiver.postMessage("Hello "+val+"!", "https://c.runoob.com");
});
}
</script>
接收程序:
接收程序有一个事件监听器,监听 "message" 事件,同时我们要验证消息来源地址,以确保是个可信的发送地址。
<div id="recMessage">
Hello World!
</div>
<script>
window.onload = function() {
var messageEle = document.getElementById('recMessage');
window.addEventListener('message', function (e) { // 监听 message 事件
alert(e.origin);
if (e.origin !== "https://www.runoob.com") { // 验证消息来源地址
return;
}
messageEle.innerHTML = "从"+ e.origin +"收到消息: " + e.data;
});
}
</script>
e.source:消息源(此处为iframe)
e.origin:消息源的URI,用于验证
e.data:发送过来的数据