webworker笔记
# 创建webWorker的目的是什么?
- 增加一个新的全局上下文来运行一个独立于主线程外的程序 从而达到性能的优化和不阻塞主线程的效果
通过使用 Web Workers,Web 应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是 UI 线程)不会因此被阻塞/放慢。
# webWorker的概念与用法
使用构造函数(例如,Worker())创建一个 worker 对象,构造函数接受一个 JavaScript 文件 URL — 这个文件包含了将在 worker 线程中运行的代码。worker 将运行在与当前 window不同的另一个全局上下文中,这个上下文由一个对象表示,标准情况下为DedicatedWorkerGlobalScope (标准 workers 由单个脚本使用; 共享 workers 使用SharedWorkerGlobalScope (en-US))。
你可以在 worker 线程中运行任意的代码,但注意存在一些例外:你不能直接在 worker 线程中操纵 DOM 元素;或使用window 对象中的某些方法和属性。大部分 window 对象的方法和属性是可以使用的,包括 WebSockets (en-US),以及诸如 IndexedDB 和 FireFox OS 中独有的 Data Store API 这一类数据存储机制。更多信息请参见: Functions and classes available to workers (en-US) 。
主线程和 worker 线程相互之间使用 postMessage() 方法来发送信息,并且通过 onmessage 这个 event handler 来接收信息(传递的信息包含在 Message 这个事件的data属性内) 。数据的交互方式为传递副本,而不是直接共享数据。
首先,创建一个worker.js文件,它将作为我们的Web Worker:
// worker.js
self.onmessage = function(event) {
const data = event.data;
console.log('Worker received message:', data);
// 执行一些耗时的任务
const result = expensiveOperation(data);
// 将结果发送回主线程
self.postMessage(result);
};
function expensiveOperation(data) {
// 模拟一个耗时的任务
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += Math.sqrt(i) * data;
}
return result;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
接下来,在主线程中创建并使用Web Worker:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web Worker Demo</title>
</head>
<body>
<h1>Web Worker Demo</h1>
<button onclick="startWorker()">Start Worker</button>
<p id="result"></p>
<script>
let worker;
function startWorker() {
if (typeof Worker !== 'undefined') {
// 创建一个新的Web Worker
worker = new Worker('worker.js');
// 监听Worker发送回来的消息
worker.onmessage = function(event) {
document.getElementById('result').textContent = 'Result: ' + event.data;
};
// 向Worker发送消息
worker.postMessage(3.14);
} else {
console.log('Web Worker not supported');
}
}
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在这个示例中:
我们创建了一个worker.js文件,它作为Web Worker运行。它监听onmessage事件,接收主线程发送的消息。在接收到消息后,它执行一个耗时的操作,并将结果发送回主线程。
在主线程中,我们使用new Worker('worker.js')创建一个新的Web Worker实例。我们监听worker.onmessage事件,以接收Worker发送回来的消息。
当点击"Start Worker"按钮时,我们向Worker发送一条消息worker.postMessage(3.14)。
Worker接收到消息后,执行耗时的操作,并将结果发送回主线程。
主线程接收到结果,并将其显示在页面上。
通过这种方式,我们可以将耗时的操作offload到Web Worker中,避免阻塞主线程,从而提高页面的响应性能。