知食记
搜索文档…
知食记
思维导图
归档
博客
🎃CSS
CSS基础
CSS3
SCSS
🎉JavaScript
JS 概念
JS陷阱
JS开发知识点
实现JS常见函数
实现JS 常见操作函数
JS Worker
Cloudflare Worker
ES6
ES6 函数
Typescript
V8
🕹️框架
Vue
Vue3
React
React-Redux
React Hooks
Nuxt
Koa2
🎯算法
算法与数据结构
🎁HTML
DOM
SVG
🏈计算机网络
浏览器
计算机网络
🥊前端生态
Webpack
Babel
Fetch
Axios
Npm
Yarn
业务开发
微前端
Hexo
🏀后端
Node
Java
Python
🕹️面试
面试真经
To-do
🤖开源
开源项目
🧸其他
Linux
Git
正则
设计模式
计算机理论
Group 1
由
GitBook
提供支持
JS Worker
背景
JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。
特点
同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
DOM限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用
document
、
window
、
parent
这些对象。但是,Worker 线程可以
navigator
对象和
location
对象。
通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
脚本限制
Worker 线程不能执行
alert()
方法和
confirm()
方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(
file://
),它所加载的脚本,必须来自网络。
数据通信
主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。需要注意的是,
这种通信是拷贝关系,即是传值而不是传址
,Worker 对通信内容的修改,不会影响到主线程。
主线程与 Worker 之间也可以交换二进制数据,比如 File、Blob、ArrayBuffer 等类型,也可以在线程之间发送。
1
// 主线程
2
var
uInt8Array
=
new
Uint8Array
(
new
ArrayBuffer
(
10
));
3
for
(
var
i
=
0
;
i
<
uInt8Array
.
length
;
++
i
)
{
4
uInt8Array
[
i
]
=
i
*
2
;
// [0, 2, 4, 6, 8,...]
5
}
6
worker
.
postMessage
(
uInt8Array
);
7
8
// Worker 线程
9
self
.
onmessage
=
function
(
e
)
{
10
var
uInt8Array
=
e
.
data
;
11
postMessage
(
'Inside worker.js: uInt8Array.toString() = '
+
uInt8Array
.
toString
());
12
postMessage
(
'Inside worker.js: uInt8Array.byteLength = '
+
uInt8Array
.
byteLength
);
13
};
Copied!
拷贝方式发送二进制数据,会造成性能问题。比如,主线程向 Worker 发送一个 500MB 文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript 允许主线程把二进制数据直接转移给子线程,但是一旦转移,
主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面
。这种转移数据的方法,叫做
Transferable Objects
。
如果要直接转移数据的控制权,就要使用下面的写法。
1
// Transferable Objects 格式
2
worker
.
postMessage
(
arrayBuffer
,
[
arrayBuffer
]);
3
4
// 例子
5
var
ab
=
new
ArrayBuffer
(
1
);
6
worker
.
postMessage
(
ab
,
[
ab
]);
Copied!
示例
通常情况下,Worker 载入的是一个单独的 JavaScript 脚本文件,但是也可以载入与主线程在同一个网页的代码。
1
<!
DOCTYPE
html
>
2
<
body
>
3
<
script id
=
"worker"
type
=
"app/worker"
>
4
addEventListener
(
'message'
,
function
()
{
5
postMessage
(
'some message'
);
6
},
false
);
7
</
script
>
8
</
body
>
9
</
html
>
Copied!
上面是一段嵌入网页的脚本,注意必须指定
<script>
标签的
type
属性是一个浏览器不认识的值,上例是
app/worker
。
然后,读取这一段嵌入页面的脚本,用 Worker 来处理。
1
var
blob
=
new
Blob
([
document
.
querySelector
(
'#worker'
).
textContent
]);
2
var
url
=
window
.
URL
.
createObjectURL
(
blob
);
3
var
worker
=
new
Worker
(
url
);
4
5
worker
.
onmessage
=
function
(
e
)
{
6
// e.data === 'some message'
7
};
Copied!
上面代码中,先将嵌入网页的脚本代码,转成一个二进制对象,然后为这个二进制对象生成 URL,再让 Worker 加载这个 URL。这样就做到了,主线程和 Worker 的代码都在同一个网页上面。
webpack
webpack有专门支持读取worker的loader: webpack-loader
具体使用见文档:
https://webpack.docschina.org/loaders/worker-loader/
为了在typescript中使用,参见issue:
https://github.com/webpack-contrib/worker-loader/issues/94
以前
JS Safe Get
下一个
Cloudflare Worker
最近更新
2yr ago
复制链接
内容
背景
特点
同源限制
DOM限制
通信联系
脚本限制
文件限制
数据通信
示例
webpack