关于Web Worker

Web Worker

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。

用法

  1. 这里的work.js是一个脚本文件
let worker = new Worker('work.js');

Web Worker 有自己的全局对象,不是主线程的window,而是一个专门为 Worker 定制的全局对象。因此定义在window上面的对象和方法不是全部都可以使用

  1. 主线程通过postMessage方法给worker传递数据,其中参数就是传递的数据
worker.postMessage('Hello World');
  1. 主线程通过监听onmessage和onerror来获取worker中的状态
worker.onmessage = function (event){
    console.log('Received message ' + event.data);
    doSomething();
}
worker.onerror = error => {
    console.log(error )
}
  1. 关闭worker。在worker结束之后,一定要关闭,因为线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断,比较耗费资源,不应该过度使用。
worker.terminate(); // 在主线程关闭worker

this.close(); // 在脚本内部关闭
  1. 同时加载多个文件,异步加载
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


注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

你可能感兴趣的:(关于Web Worker)