今天面试被问到了浏览器怎么开启一个子线程处理任务
嗯?嗯嗯嗯?浏览器不是单线程吗 哪来的开启子线程。面试结束立马查阅资料,还别说真的有,赶紧学习
WebWorker
Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,它们可以使用 XMLHttpRequest(尽管 responseXML 和 channel 属性总是为空)或 fetch(没有这些限制)执行 I/O。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理器(反之亦然)。 (引用MDN)
简单来说就是,web worker 可以让JS从单线程变成多线程,666,那么好,下次在有人问怎么处理百万数据就有答案了,我直接开启一个子线程,言归正传,下变记录一下实现过程
先创建一个空白的html文件, 简单写一下通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="liqiang"></div>
<div id="zhaosi"></div>
<div id="wangwu"></div>
</body>
<script>
const worker = new Worker('./worker.js', { type: 'module' })
worker.addEventListener('message', function({ data }) {
switch(data.type) {
case "liqiang":
document.getElementById('liqiang').textContent = `我叫${data.name}, 今年${data.age}岁`
break
case "zhaosi":
document.getElementById('zhaosi').textContent = `我叫${data.name}, 今年${data.age}岁`
break;
case "wangwu":
document.getElementById('wangwu').textContent = `我叫${data.name}, 今年${data.age}岁`
break;
}
})
worker.postMessage({
type: 'liqiang',
name: '李强',
age: 18
})
worker.postMessage({
type: 'zhaosi',
name: '赵四',
age: 19
})
worker.postMessage({
type: 'wangwu',
name: '王五',
age: 20
})
// 终止worker
// myWorker.terminate();
</script>
</html>
worker.js
self.addEventListener("message", function({ data }) {
switch(data.type) {
case "liqiang":
self.postMessage(data)
break;
case "zhaosi":
self.postMessage(data)
break;
default:
self.postMessage(data)
break;
}
})
用 http-server 运行一下得到的结果
原理其实到这里就搞懂了那么下边开始做一下扩展模拟一下大数据量加载
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web Worker</title>
</head>
<body>
<button id="sortButton">排序</button>
<div id="result"></div>
<script>
// 创建Worker实例
const worker = new Worker('worker.js', { type: 'module' });
document.getElementById("sortButton").addEventListener("click", () => {
const largeArray = Array.from({ length: 1000000 }, () =>
Math.floor(Math.random() * 100000)
);
console.log("开始排序...");
const startTime = performance.now();
// 向 Worker 发送数据
worker.postMessage({ type: "sort", array: largeArray });
// 接收 Worker 返回的结果
worker.onmessage = function (event) {
const { data } = event;
if (data.type === "result") {
const endTime = performance.now();
console.log("排序完成:", data.sortedArray);
document.getElementById(
"result"
).innerText = `排序完成,用时:${(endTime - startTime).toFixed(2)} ms`;
}
};
});
</script>
</body>
</html>
worker.js
// 接收主线程的数据
self.onmessage = function (event) {
const { data } = event;
if (data.type === "sort") {
const sortedArray = data.array.sort((a, b) => a - b);
// 将结果发送回主线程
self.postMessage({ type: "result", sortedArray });
}
};
到这里关于worker的运用已经掌握的差不多了,最后说一句 前端已死