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 使用場景,謝謝閱讀!