场景 :你正在上传一个10GB的蓝光电影,突然发现——
为啥会这样?
浏览器只有一个主线程,既要渲染页面,又要处理上传任务。大文件上传时,主线程被“霸占”,页面自然卡顿!
😤 用户内心OS :传个文件而已,至于让我电脑爆炸吗?
💡 类比 :主线程是厨师,Web Worker是切菜工。厨师只管炒菜,切菜交给小弟!
⚠️ 注意 :别用Worker处理简单任务!创建线程本身也有开销,杀鸡别用牛刀。
新建一个upload.worker.js,专门处理上传逻辑:
// upload.worker.js
self.onmessage = function(e) {
const file = e.data;
// 1. 分片处理
const chunkSize = 5 * 1024 * 1024; // 每片5MB
const chunks = [];
for (let i = 0; i < file.size; i += chunkSize) {
chunks.push(file.slice(i, i + chunkSize));
}
// 2. 告诉主线程:分片完成啦!
self.postMessage({ type: 'chunks', chunks });
};
// 主页面代码
const worker = new Worker('upload.worker.js');
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
worker.postMessage(file); // 把文件扔给Worker处理
});
// 接收Worker的消息
worker.onmessage = (e) => {
if (e.data.type === 'chunks') {
const chunks = e.data.chunks;
// 上传分片(这里可以用axios循环发送)
}
};
const workerCode = `self.onmessage = function(e) { ... }`;
const blob = new Blob([workerCode], { type: 'text/javascript' });
const worker = new Worker(URL.createObjectURL(blob));
worker.onerror = (e) => {
console.error('Worker出错啦:', e.message);
};
实战建议 :
大文件上传:用Worker分片 + 主线程控制上传队列。
配合axios的取消令牌,实现“断点续传”。
记得在页面卸载时终止Worker:worker.terminate()!