大文件上传
大文件上传
切片上传,获取文件,以及每个切片的md,这一步相对耗时较长,且堵塞渲染主线程断点续传,每次上传之前,将文件md5值、切片数量、每个切片md5传给后台,后台告知该文件是否上传过,上传了哪些切片,已上传的暂不处理(之前上传中的切片认为未上传,所以考虑每个切片的体积较小,为1M)处理并发,不能一次性调用一百次上传接口,每完成一个新增一个上传任务多线程解析,因解析文件耗费较长时间,且会堵塞渲染
大文件上传
- 切片上传,获取文件,以及每个切片的md,这一步相对耗时较长,且堵塞渲染主线程
- 断点续传,每次上传之前,将文件md5值、切片数量、每个切片md5传给后台,后台告知该文件是否上传过,上传了哪些切片,已上传的暂不处理(之前上传中的切片认为未上传,所以考虑每个切片的体积较小,为1M)
- 处理并发,不能一次性调用一百次上传接口,每完成一个新增一个上传任务
- 多线程解析,因解析文件耗费较长时间,且会堵塞渲染主线程,需开启多线程解析文件及切片md5
第一步,设计worker,引入md5依赖,解析文件/切片的md5和c
代码语言:javascript代码运行次数:0运行复制importScripts('./md5.js');
ct handleFileReader = (file) => {
return new Promise((resolve, reject) => {
ct reader = new FileReader();
ct spark = new SparkMD5.ArrayBuffer();
= (e) => {
ct arrayBuffer = result;
spark.append(arrayBuffer); // 计算 MD5
ct md5 = (); // 获取最终结果
resolve(md5);
};
reader.readAsArrayBuffer(file);
})
}
= async (event) => {
ct { file, cSize } = event.data;
ct spark = new SparkMD5.ArrayBuffer();
ct cs = (file.size / cSize);
ct md5 = await handleFileReader(file);
self.postMessage({ type: 'file_md5', md5: md5, total: cs, });
for (let i = 0; i < cs; i++) {
ct start = i * cSize;
ct end = (file.size, start + cSize);
ct c = file.slice(start, end);
ct md5 = await handleFileReader(c);
self.postMessage({ type: 'c', md5: md5, c: c, index: i, });
}
self.postMessage({ type: 'done', hash: () });
();
};
第二步,设计上传
代码语言:javascript代码运行次数:0运行复制let preparedCs = []; // 存储分片
let fileMd5 = ''; // 整个文件的md5
let totalSize = 0; // 切片总数
let uploadedCount = 0; // 已经上传的切片数量
let doingCount = 0; // 正在上传的任务数量
let maxum = 5; // 上传并发最多多少
let taskList = []; // 上传任务
let uploadedCList = []; // 已经上传过的切片
// 处理上传并发
ct doTask = () => {
while (doingCount < maxum && taskList.length) {
ct { task, resolve, reject, } = taskList.shift();
doingCount = doingCount + 1;
task().then((res) => {
if (uploadedCount == totalSize) {
cole.log('全部上传完了--doTask:', 111);
} else {
ct progress = Math.floor((uploadedCount / totalSize) * 100).toFixed(1);
cole.log('上传中--doTask:', `${ progress }%`);
}
resolve(res)
}).catch((error) => {
reject(error);
}).finally(() => {
doingCount = doingCount - 1;
doTask();
})
}
}
// 追加上传任务
ct addTask = (task) => {
return new Promise((resolve, reject) => {
taskList.push({
task,
resolve,
reject
})
doTask();
})
}
// 上传每个切片
ct uploadCs = async (c, md5) => {
await getUploadedCs(fileMd5);
if (uploadedCList.includes(md5)) {
return new Promise((resolve, reject) => {
uploadedCount = uploadedCount + 1;
resolve();
})
}
ct task = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
uploadedCount = uploadedCount + 1;
resolve();
}, Math.round(Math.random() * 2 * 1000));
})
}
addTask(task).then((res) => {
cole.log('taskList--uploadCs:', taskList.length);
});
}
// 获取文件,以及每个切片和对应的切片md5
async function calculateFileHash(file) {
return new Promise((resolve, reject) => {
ct worker = new Worker('worker.js');
ct cSize = 100 * 1024 * 1024;
ct md5 = new SparkMD5.ArrayBuffer();
worker.postMessage({ file, cSize, md5 });
= (event) => {
ct { type, md5, c, total, index, } = event.data;
if (type === 'file_md5') {
fileMd5 = md5;
totalSize = total;
getUploadedCs(md5);
} else if (type === 'c') {
cole.log('md5, c--calculateFileHash:', md5, c);
preparedCs.push({
md5: md5,
c: c,
index: index,
})
uploadCs(md5, c);
}
if (preparedCs.length == total) {
resolve();
}
};
= (error) => {
reject(error);
};
});
}
// 获取已上传的切片
async function getUploadedCs(fileHash) {
return new Promise((resolve, reject) => {
// 如何已请求,直接return
if (uploadedCList.length) {
resolve();
return;
}
setTimeout(() => {
// mock之前已上传的切片
uploadedCList = [
{ c: '', },
]
resolve();
}, Math.round(Math.random() * 2 * 1000));
})
}
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上传时间: 2025-07-22 12:39:25
留言与评论(共有 11 条评论) |
本站网友 治疗口臭 | 19分钟前 发表 |
md5 | |
本站网友 仁品耳鼻喉 | 22分钟前 发表 |
md5 | |
本站网友 拔火罐注意事项 | 26分钟前 发表 |
将文件md5值 | |
本站网友 孩子为什么厌学 | 26分钟前 发表 |
reject) => { // 如何已请求 | |
本站网友 乌鲁木齐新楼盘 | 5分钟前 发表 |
设计worker | |
本站网友 电信路 | 6分钟前 发表 |
' | |
本站网友 病例格式 | 18分钟前 发表 |
获取文件 | |
本站网友 冒险岛sf发布网 | 6分钟前 发表 |
c | |
本站网友 权力游戏第二季 | 11分钟前 发表 |
大文件上传 切片上传 | |
本站网友 linuxqq | 4分钟前 发表 |
} |