意义

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

限制

(1)同源限制

分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。

(2)DOM 限制

Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用documentwindowparent这些对象。但是,Worker 线程可以navigator对象和location对象。

(3)通信联系

Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

(4)脚本限制

Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。

(5)文件限制

Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

Web Worker使用

var worker=new Worker(jsUrl).;

数据通信

主线程

//1.发送消息
worker.postMessage(data);
//2.接受信息
worker.onmessage = function (event) {
console.log('Received message ' + event.data);
// doSomething();
}
//self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
//3.关闭Worker
worker.terminate();
//4.错误处理
worker.onerror(function (event) {
//dosomething
});
//5.关闭
self.close()

Worker线程

//1.接收消息
self.addEventListener('message', function (e) {

}, false);
//self=this=(不写)
//2.发送消息
self.postMessage('You said: ' + data);
//3. 加载脚本
importScripts('script1.js');

主线程与 Worker 之间的通信内容是拷贝关系,事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。但这种方式有一弊端就是发送大文件过去Worker时,这种拷贝的方式会造成造成性能问题;

为了解决这一问题,出现一种转移数据的方式称作Transferable Objects

Transferable Objects使用方式:

// Transferable Objects 格式
worker.postMessage(arrayBuffer, [arrayBuffer]);

var buffer=new ArrayBuffer(1);
worker.postMessage(buffer,[buffer]);

Blob createObjectURL使用

Blob: 二进制类型的大对象

使用:

var blob=new Blob(blobParts, options);

相关的参数说明如下:

  • blobParts:它是一个由 ArrayBuffer,ArrayBufferView,Blob,DOMString 等对象构成的数组。DOMStrings 会被编码为 UTF-8。

  • options:一个可选的对象,包含以下两个属性:

    • type —— 默认值为 "",它代表了将会被放入到 blob 中的数组内容的 MIME 类型。(text/html text/javaScript)等
    • endings —— 默认值为 "transparent",用于指定包含行结束符 \n 的字符串如何被写入。它是以下两个值中的一个:"native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持 blob 中保存的结束符不变

使用场景:

  1. 文件分片上传(FILE对象是特殊类型的Blob)

  2. 互联网下载数据

    当 fetch 请求成功的时候,我们调用 response 对象的 blob() 方法,从 response 对象中读取一个 Blob 对象,然后使用 createObjectURL() 方法创建一个 objectURL,然后把它赋值给 img 元素的 src 属性从而显示这张图片。

  3. Blob 用作 URL

createObjectURL

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。

  • objectURL = URL.createObjectURL(object);

object :用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。

实例

  1. 实现setInterval
const mySetInterval = (func, interval) = > {
if (typeof window !== 'undefined' && window.Worker && window.Blob) {
const check = new Blob(["(",
function() {
self.onmessage = function(e) {
const interval = e.data;
let startTime = Date.now();
while (true) {
if (Date.now() - startTime >= interval) {
startTime = Date.now();
self.postMessage(Date.now());
}
}
}
}.toString(), ")()"
], {
type: "text/javascript"
});
const worker = new Worker(window.URL.createObjectURL(check));
worker.onmessage = func;
worker.postMessage(interval);
return worker;
} else {
console.log('Your environment is not supported');
}
}
const myClearInterval = config = > {
config.terminate()
}
  1. 文件分块上传
const file = new File(["a".repeat(1000000)], "test.txt");

const chunkSize = 40000;
const url = "https://httpbin.org/post";

async function chunkedUpload() {
for (let start = 0; start < file.size; start += chunkSize) {
const chunk = file.slice(start, start + chunkSize + 1);
const fd = new FormData();
fd.append("data", chunk);

await fetch(url, { method: "post", body: fd }).then((res) =>
res.text()
);
}
}

参考

Web Worker 使用教程 - 阮一峰的网络日志 (ruanyifeng.com)

JavaScript中的Blob你知道多少 - 知乎 (zhihu.com)