Web Worker
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。
用法
- 这里的work.js是一个脚本文件
let worker = new Worker('work.js');
Web Worker 有自己的全局对象,不是主线程的window,而是一个专门为 Worker 定制的全局对象。因此定义在window上面的对象和方法不是全部都可以使用
- 主线程通过postMessage方法给worker传递数据,其中参数就是传递的数据
worker.postMessage('Hello World');
- 主线程通过监听onmessage和onerror来获取worker中的状态
worker.onmessage = function (event){
console.log('Received message ' + event.data);
doSomething();
}
worker.onerror = error => {
console.log(error )
}
- 关闭worker。在worker结束之后,一定要关闭,因为线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断,比较耗费资源,不应该过度使用。
worker.terminate(); // 在主线程关闭worker
this.close(); // 在脚本内部关闭
- 同时加载多个文件,异步加载
importScripts('script1.js', 'script2.js');
runAsync
runAsync函数返回一个promise对象,将传入的函数放置于第二线程执行,可以用来处理耗时过长的的计算,防止页面卡顿
const runAsync = fn => {
const worker = new Worker(
URL.createObjectURL(new Blob([`postMessage((${fn})());`]), {
type: 'application/javascript; charset=utf-8'
})
);
return new Promise((res, rej) => {
worker.onmessage = ({ data }) => {
res(data), worker.terminate();
};
worker.onerror = err => {
rej(err), worker.terminate();
};
});
};
用法
runAsync( fn ).then( console.log );
URL.createObjectURL(new Blob([postMessage((${fn})());
]), { type: 'application/javascript; charset=utf-8' }) 会生成一个url
(注1)
使用须知
- 分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源
- Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象
- Worker 线程可以使用 XMLHttpRequest 对象发出 AJAX 请求。
注1:关于Blob,是一种JavaScript的对象类型,blob 存储着大量的二进制数据,并且 blob 的 size 和 type 属性,都会被 file 对象所继承
下面的栗子会使用URL.createObjectURL + Blob生成一段url并添加iframe到页面中,执行后会在页面中显示div
<script type="text/javascript">
let div = '<div style="font-size:32px;color:red;">文字</div>'
let url = new Blob([div], { type: 'text/html' })
onload=function(){
var iframe=document.createElement("iframe");
iframe.src=URL.createObjectURL(url, {type: 'text/html;'})
document.body.appendChild(iframe);
};
</script>
注2:更多详情请参考
http://www.ruanyifeng.com/blog/2018/07/web-worker.html --- 阮一峰
https://github.com/30-seconds/30-seconds-of-code?utm_source=caibaojian.com --- github