1. 介绍
WebWorker 允许开发者在Web上创建多线程,对于计算密集型操作,可以大大优化web应用性能。
但是WebWorker文档中只介绍了 是由url来创建一个worker,使用webpack时使用worker-loader 时,通过 inline: true
的选项可以创建一个内联worker。
如果不使用webpack或worker-loader时应该怎么操作呢?
答案是通过Blob,worker-loader也是这么做的。
2. 代码示例
Blob 对象表示一个不可变、原始数据的类文件对象。大概意思就是 Blob就相当是浏览器上的文件,可以通过 blob生成一个js文件,再给Worker加载,上代码:
let code = /*javascript*/`
this.addEventListener('message', function (e) {
this.postMessage('You said: ' + e.data);
}, false);
`
function codeToBlob (code) {
let blob = new Blob([code], {type: 'text/javascript'}); // 生成js文件对象
let objectURL = window.URL.createObjectURL(blob); // 生成js文件的url
return objectURL;
}
let worker = new Worker(codeToBlob(code)); // 使用 blob对象的url
worker.onmessage = function (event) {
console.log('Received message ' + event.data);
}
worker.postMessage('Work done!');
把上面这段代码复制到f12控制台运行,你就可以得到Worker返回的消息了
不过有的站点做了安全拦截就不行,比如npmjs.com
当然如果是部署在你自己的站点那就肯定没有这个问题啦!
3. 解读
看看上面这一段代码,其实很简单的,blob就有这么强大,让你可以在web上凭空生成一个文件,除此之外,通过这个骚操作你还可以实现 web 下载文件,不通过eval
或者new Function
来执行js代码,我们一一来演示一下:
演示之前,对我们上面例子优化一下,就是code这里不能js代码高亮,在vscode里我们只需要下载一个 es6-string-javascript
插件就然后再es6字符串前面加上/*javascript*/
前缀就可以了,体验相当的好!
4.通过Blob下载文件
一般下载文件都是通过 a标签
加一个 download属性
来下载一个url对应的文件:
<a href="http://xxx" download="xxx.js"></a>
这样就能下载一个 xxx.js 文件了,但是我如果想通过一段代码字符串来生成一个js文件并且下载呢?
还得通过Blob,还是先上代码:
function download (code, name) {
let downloadLink = document.createElement('a');
downloadLink.setAttribute('style', 'position: fixed;top: -100px');
document.body.appendChild(downloadLink);
downloadLink.setAttribute('download', name);
let blob = new Blob([code], {type: 'text/javascript'});
let url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.click();
document.body.removeChild(downloadLink);
}
download('console.log("Hello World");', 'hello.js');
把上面的代码放到f12,控制台运行你就可以自动下载一个 hello.js 文件了,举一反三,你可以通过这种方式下载任何文件…
5.通过Blob执行js代码
这也是一个比较常见的场景,执行一段js代码,一般我们可以使用 eval
和new Function
,我们使用Blob看看如何执行js代码
function exeJs (code) {
let blob = new Blob([code], {type: 'text/javascript'});
let objectURL = window.URL.createObjectURL(blob);
script = document.createElement('script');
script.onload = () => {
console.log('loaded')
};
script.src = objectURL;
document.body.appendChild(script);
}
exeJs('console.log("hello world");')
运行结果:
实现方式大同小异,就不一一解释了。
以上就是总结的一些 Blob 使用场景,谢谢阅读!