Web Worker是一个可以让JavaScript在浏览器上跑多个进程的方案,它可以让JavaScript不阻塞UI线程,大大提高网页的性能和用户体验。Web Worker是HTML5标准里的一部分,目前主流的现代浏览器都支持Web Worker。
Web Worker的基础知识
什么是Web Worker?
Web Worker是一种JavaScript API,它可以在浏览器的后台开辟一个或多个线程运行JavaScript代码,不影响UI线程(也就是不会卡死页面)。Web Worker使得JavaScript可以通过多线程的方式同时处理多个任务,从而更快地完成复杂操作。
Web Worker的特性
Web Worker拥有以下特性:
- 每个Web Worker运行于独立的线程中;
- Web Worker之间无法直接通信,只能通过消息传递的方式进行通信;
- Web Worker可以与父线程(主线程)通信;
- Web Worker不可使用window、document等DOM对象,但可使用XMLHttpRequest发起HTTP请求。
Web Worker的工作原理
Web Worker的工作流程如下:
- 在主线程中创建一个Web Worker对象;
- 将需要运行的JS文件传给这个Web Worker对象,并让它开始运行;
- 等待Web Worker执行完毕并返回结果;
- 在主线程中接收到Web Worker返回的结果后进行处理。
实例演示
下面通过两个示例说明Web Worker的使用方法。
示例一
在这个示例中,我们将演示如何使用Web Worker进行大量计算,以及如何将计算结果传回主线程。
- 创建一个index.html文件:
<!DOCTYPE html>
<html>
<head>
<title>Web Worker示例一</title>
</head>
<body>
<h1>Web Worker示例一</h1>
<button id="btn">开始计算(Web Worker)</button>
<button id="btn2">开始计算(单线程)</button>
<br>
<br>
<div id="result"></div>
<script>
window.onload = function() {
var btn = document.getElementById('btn');
var btn2 = document.getElementById('btn2');
var result = document.getElementById('result');
var worker = new Worker('worker.js');
btn.onclick = function() {
worker.postMessage(10000);
}
worker.onmessage = function(event) {
result.innerHTML = 'Web Worker 计算结果:' + event.data;
}
btn2.onclick = function() {
var start = Date.now();
var result = 0;
for (var i = 0; i < 100000000; i++) {
result += Math.pow(2, 20);
}
var end = Date.now();
var time = end - start;
result.innerHTML = '单线程计算结果:' + result + ',耗时:' + time + 'ms';
}
}
</script>
</body>
</html>
- 创建一个worker.js文件:
onmessage = function(event) {
var start = Date.now();
var result = 0;
for (var i = 0; i < event.data * 1000000; i++) {
result += Math.pow(2, 20);
}
var end = Date.now();
var time = end - start;
postMessage(result + ',耗时:' + time + 'ms');
}
在这个示例中,我们在主线程中创建了一个Web Worker对象worker,并将需要传递的参数(10000)使用postMessage方法传入到worker中。worker.js执行计算任务,将结果通过postMessage方法传递回主线程,在主线程中使用worker.onmessage方法接收到这个结果。同时,我们也创建了一个button(btn2),使用单线程计算,用于比较时间和结果的差异。
示例二
在这个示例中,我们将演示如何使用Web Worker加载图片,以及如何将加载结果传回主线程。
- 创建一个index.html文件:
<!DOCTYPE html>
<html>
<head>
<title>Web Worker示例二</title>
</head>
<body>
<h1>Web Worker示例二</h1>
<button id="btn">开始加载图片(Web Worker)</button>
<button id="btn2">开始加载图片(单线程)</button>
<br>
<br>
<div id="result"></div>
<script>
window.onload = function() {
var btn = document.getElementById('btn');
var btn2 = document.getElementById('btn2');
var result = document.getElementById('result');
var worker = new Worker('worker.js');
btn.onclick = function() {
worker.postMessage('https://mdn.mozillademos.org/files/5395/catfront.png');
}
worker.onmessage = function(event) {
result.innerHTML = '<img src="' + event.data + '">';
}
btn2.onclick = function() {
var start = Date.now();
var img = new Image();
img.onload = function() {
var end = Date.now();
var time = end - start;
result.innerHTML = '<img src="' + img.src + '">' + ',耗时:' + time + 'ms';
}
img.src = 'https://mdn.mozillademos.org/files/5395/catfront.png';
}
}
</script>
</body>
</html>
- 创建一个worker.js文件:
onmessage = function(event) {
var xhr = new XMLHttpRequest();
xhr.open('GET', event.data, true);
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.readAsDataURL(xhr.response);
reader.onload = function(e) {
postMessage(reader.result);
}
}
xhr.send();
}
在这个示例中,我们在主线程中创建了一个Web Worker对象worker,并使用postMessage方法将需要下载的图片url传入。worker.js下载这个图片并转换成base64编码的字符串,使用postMessage方法将字符串传回主线程,在主线程中使用worker.onmessage方法接收到这个字符串,并使用img标签将图片显示在页面上。同时,我们也创建了一个button(btn2),使用单线程下载图片,用于比较时间和结果的差异。
通过这两个示例我们可以了解到Web Worker的使用方法,同时也可以明白Web Worker对于性能的提升有很大的效果,能够为网页带来更好的用户体验。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js多线程解决方案Web Worker简单说明与实例演示 - Python技术站