Web Worker 的使用
Youky ... 2022-10-16 About 1 min
# Web Worker 的使用
# 1. 意义
由于 JS 是单线程的,费时的 JS 操作将会导致整个页面的阻塞。Web Worker 提供了创建多线程的方法,将一些耗时且 UI 无关的工作交给 worker,可提高页面的使用体验。
限制:
- 同源策略:worker 线程执行的脚本要和当前页面同源
- API 限制:
- 不能操作 DOM
- 不能使用 window 的全局变量,但可以使用 navigator 和 location 对象
- 不能使用 alert、confirm 方法
- 无法读取本地文件
- 和主线程不在一个上下文环境,通讯要通过
postMessage
完成
# 2. 主线程的使用
# 创建
创建一个子线程,要传入一个脚本的 URL。如果该脚本加载失败,则 Worker 会静默失败
const worker = new Worker('url');
1
如果要在本文件中描述执行的内容,可以用 Blob 和 window.URL.createObjectURL 生成一个 URL
function createWorker(f) {
const blob = new Blob(['(' + f.toString() +')()']);
const url = window.URL.createObjectURL(blob);
const worker = new Worker(url);
return worker;
}
1
2
3
4
5
6
2
3
4
5
6
# 通信
- 主线程 => 子线程
worker.postMessage(param);
1
参数可以是任意类型,包括二进制数据。但传递是拷贝形式而不是引用形式。因此对于大数据会存在性能问题。
- 子线程 => 主线程
worker.onmessage = function (event) {
console.log('Received message ' + event.data);
}
1
2
3
2
3
# 错误处理
worker.onerror(function (e) {
console.log([
'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
].join(''));
});
1
2
3
4
5
2
3
4
5
# 关闭
worker.terminate();
1
# 3. 子线程的使用
子线程中无法使用 window,self
代表全局对象
# 和主线程的通信
- 主线程 => 子线程
self.addEventListener('message', function (e) {
self.postMessage('Received: ' + e.data);
}, false);
1
2
3
2
3
- 子线程 => 主线程
self.postMessage('something');
1
# 加载其他脚本
在子线程中加载其他脚本:
importScripts('script1.js', 'script2.js');
1
# 关闭
self.close();
1