JS workers.js实现多线程以及实现子线程使用self之外的对象,如window对象
在 Web Workers 中,self.postMessage 用于向主线程发送消息,但 Web Workers 本身不具备等待主线程回复的机制。不过,可以使用 Promises 和消息事件来实现异步通信,从而在 Worker 中等待主线程的回复后再继续执行后续代码
emm…本文不提供安装workers.js,因为我使用的是vue3+vite,不需要安装
子线程使用self之外的对象 示例代码
- Worker 脚本 (worker.js)
worker.js这个名字自己可以随便定义, 随便放在哪个目录下都行,只要记住路径就行
// worker.js
self.addEventListener('message', async function(event) {
if (event.data === 'start') {
// 这里就是处理你子线程的东西
console.log('Worker: 收到的启动消息。等待主线程的回复');
// 下面代码是给主线程发送消息然后叫主线程执行某些操作,并同步的返回回来
// 发送消息到主线程,并等待回复
await sendMessageAndWaitForReply('Hello from worker');
console.log('2');
}
});
// 发送消息并等待回复的函数
function sendMessageAndWaitForReply(message) {
return new Promise((resolve, reject) => {
// 监听消息事件
function onMessage(event) {
if (event.data.replyTo === message) {
self.removeEventListener('message', onMessage);
resolve(event.data.reply);
}
}
self.addEventListener('message', onMessage);
// 发送消息到主线程
self.postMessage({ message, replyTo: message });
});
}
- 主线程脚本 (main.js)
// main.js
const worker = new Worker(new URL('workers/workers.js', import.meta.url), { type: 'module' });
// const worker = new Worker('workers/worker.js');
// 监听 Worker 发送的消息
worker.addEventListener('message', function(event) {
console.log('主线程: 收到子线程的消息:', event.data);
if (event.data === 'Hello from worker') {
// 处理一些事情
setTimeout(() => {
// 回复 Worker
worker.postMessage({ reply: 'Hello from main thread', replyTo: 'Hello from worker' });
}, 1000)
} else if (event.data === 'Continuing after reply') {
console.log('子线程已经处理完成');
}
});
// 向 Worker 发送开始消息
worker.postMessage('start');
如果想等所有子线程都完成后再告诉用户说所有的任务都完成
主线程脚本 (main.js)
const array = [{id: 1},{id: 2},{id: 3},{id: 4},{id: 5},{id: 6},{id: 7},{id: 8},{id: 9}];
const numberOfThreads = 4;
const chunkSize = Math.ceil(array.length / numberOfThreads);
const chunks = [];
// 拆分多个线程
for (let i = 0; i < numberOfThreads; i++) {
let list = array.slice(i * chunkSize, (i + 1) * chunkSize);
let data = {
name: '',
list: list
}
chunks.push(data);
}
console.log(chunks)
const workerPromises = [];
// 创建 Workers 并处理每个子集合
const workers = chunks.map((chunk, index) => {
const worker = new Worker(new URL('workers/mixed-clip-workers.js', import.meta.url));
// const worker = new Worker('workers/worker.js');
worker.postMessage(chunk);
const workerPromise = new Promise((resolve) => {
worker.onmessage = (event) => {
console.log(event.data);
// 完成后记得销毁掉子线程
worker.terminate()
resolve(); // 如果收到消息就Promise,注意, 如果想要更复杂的操作可以结合上面的示例代码来写
};
worker.onerror = function(e) {
worker.terminate()
reject(new Error(`Worker error: ${e.message}`));
};
});
workerPromises.push(workerPromise);
});
// 所有子线程都完成了
Promise.all(workerPromises).then(() => {
console.log("全部完成")
}).finally(() => {
});
上面代码已经跑通了,如出现错误,仔细研究一下,或评论区留言一下