js worker使用总结
文章目录概述一、使用步骤创建worker消息通信销毁worker简单示例二、数据共享三、外部引用四、自动创建五、其他worker使用electron中使用workernodejs中使用worker六、共享worker(SharedWorker)简单使用使用用途七、API主进程子进程概述Worker 接口是 Web Workers API 的一部分。执行URL指定的脚本,可以使用 Blob、URL
文章目录
概述
web worker就是在web应用程序中使用的worker。这个worker是独立于web主线程的,在后台运行的线程。
web worker的优点就是可以将工作交给独立的其他线程去做,这样就不会阻塞主线程。
一、使用步骤(web worker)
创建worker
创建一个基础的worker,通过传入脚本url地址,即可创建一个worker实例:
const work = new Worker(url);
消息通信
主进程:
// 监听接收worker进程信息
work.onmessage = (e) => console.log(`接收到worker传递的信息:${e.data}`);
// 发送信息到worker进程
work.postMessage('内容');
传递的数据类型包含:String、Number、Object、Array等JavaScript标准类型。
worker子进程:
// 监听接收主进程信息
self.onmessage = (e) => console.log(`接收到主进程发送的信息:${e.data}`);
// 发送信息到主进程
self.postMessage('内容');
在子进程中,self代表worker子进程的全局对象,也可以用this代替self,或者省略也行。
销毁worker
work.terminate();
简单示例
主进程代码:
const work = new Worker('work.js');
work.postMessage('hello worker')
work.onmessage = (e) => {
console.log(`主进程收到了子进程发出的信息:${e.data}`);
// 主进程收到了子进程发出的信息:你好,我是子进程!
work.terminate();
};
worker子进程代码(work.js):
onmessage = (e) => {
console.log(`收到了主进程发出的信息:${e.data}`);
//收到了主进程发出的信息:hello worker
postMessage('你好,我是子进程!');
}
二、数据共享
主线程与 Worker 之间的通信是拷贝关系,Worker 对通信内容的修改,不会影响到主线程。但是以拷贝方式发送二进制数据,会造成性能问题,为了解决这个问题,JavaScript 允许主线程把对象引用直接转移给子线程,对象引用转移后,原先上下文就无法访问此对象了,需要在 Web Workers 再次将对象还原到主线程上下文后,主线程才能正常访问被转交的对象。这种转移数据的方法,叫做Transferable Objects。
let arr = new ArrayBuffer(100);
worker.postMessage(arr, [arr]);
三、外部引用
在worker子进程中,还可以引用其他的js文件到worker中进行使用,代码如下:
worker子进程
importScripts('./importScript.js');
console.log(importName); // 外部引用的js
console.log(start(2)); // 4
importScript.js
importName = '外部引用的js';
let start = (e) => e ** 2 ;
四、自动创建
通常情况下,worker是需要加载一个单独的js文件,但是也可以通过一些方法加载页面中的一些方法函数,原理就是把函数方法转换成一个blob类型之后,再转换成一个url类型,如下:
// 方式1,函数直接转换
function workCode() {
onmessage = (e) => {
postMessage('你好,我是子进程!');
}
}
workBlob = new Blob([`(${workCode.toString ()})()`]); // 把函数转成一个自执行函数
workBlob = new Blob([workCode.toLocaleString().match(/(?:\/\*[\s\S]*?\*\/|\/\/.*?\r?\n|[^{])+\{([\s\S]*)\}$/)[1]]) // 把函数的主体内容拿出来进行转换
// 方式2,通过字符串的方式
const workCode = `
onmessage = (e) => {
postMessage('你好,我是子进程!');
}
`
workBlob = new Blob ([workCode]);
// 创建方法
const url = URL.createObjectURL(workBlob);
const worker = new Worker(url);
五、其他worker的使用
electron中使用worker
如果需要再electron中使用worker的话,需要在创建界面的时候需把 webPreferences 中的 nodeIntegrationInWorker 选项设置为true;
const win = new BrowserWindow(
……
webPreferences: {
nodeIntegrationInWorker: true
}
})
根据官方版本升级日志中,发现在4.2.9之后加入worker功能。在开启worker设置之后,可以在worker子进程中使用require等功能。
nodejs中使用worker
个人了解并不算多,待以后更新,可以参考nodejs官方网站。
六、共享worker(SharedWorker)
共享worker可以让多个页面共同使用一个worker,根据指定共同js脚本url来共享子进程,从而可以通过一个worker和多个主进程进行通信,可使用的场景:多页面数据传输、跨页面交互等功能。
示例代码:
页面1
const work = new SharedWorker('./work_share.js');
work.port.start();
work.port.postMessage('我是界面1');
work.port.onmessage = function(e) {
console.log(e.data);
// 收到了信息:我是界面1
}
页面2
const work = new SharedWorker('./work_share.js');
work.port.start();
work.port.postMessage('我是界面2');
work.port.onmessage = function(e) {
console.log(e.data);
// 收到了信息:我是界面2
}
共享worker(work_share.js)
let savePorts = [];
onconnect = function(e) {
var port = e.ports[0];
savePorts.push(port);
port.addEventListener('message', function(e) {
sendMessage(e.data);
});
port.start();
}
let sendMessage = (info) => {
for(let p = 0;p < savePorts.length; p++) savePorts[p].postMessage(`当前共享页面个数:${savePorts.length},收到了信息:${info}`);
}
更多推荐
所有评论(0)