React antd 大文件上传流程的大概梳理
介绍:
使用antd中Upload上传文件过后会得到一个流,而这个流的大小就是文件的大小
文件切片:
切片完成后就使用上传接口,使用 Promise.all方法将所有的请求合并,假设分了30份,就发30次请求。
// 文件切片
// 一份切片的大小 这里是10M
const MB = 1024 * 1024 * 10;
// 存放切片的数组
const fileArr = [];
// 获取切片的份数
const copies = Math.ceil(file?.size / MB);
// 切片过程 不可使用索引进行切片
for (let index = 0; index < copies; index++) {
if (index < copies - 1) {
fileArr.push(file.slice(MB * index, MB * (index + 1)));
} else {
fileArr.push(file.slice(MB * index, file?.size));
}
}
优化点:
因浏览器接口的过期时间的限制,当带宽过低时上传到一半所有接口都崩溃了,这肯定体验就很不好,我们可以做成分次请求,假设一共30个分片,一次请求10个分片,10个分片上传完毕在请求下面10个分片。这个我们可以使用Promise.all方法加递归实现。
// 模拟接口
const createPre = (key)=>{
return new Promise((resolve, reject) => {
resolve(key)
})
}
// 假设切片的份数
const fileArr = 40;
// 获取每份一次请求的个数
const erveyData = 10;
// 递归函数
const recursion = (i)=>{
// 用来装一次请求10分的数组
const connector = [];
// 获取当前递归最后索引值
const targetIndex = i + erveyData <= arr.length - 1 ? i + erveyData : fileArr;
// 循环
for (let index = i; index < targetIndex; index++) {
connector.push(
createPre(i),
);
}
// 请求接口
Promise.all(connector)
.then(() => {
if (targetIndex !== arr.length - 1) {
recurrence(i + erveyData);
}
})
.catch(() => {
reject(false);
});
}
recursion(0);
上传大文件的基本流程就是这样,还有一个其他的辅助功能例如计算md5值当md5值重复文件不用再次上传,上传多个文件需要评分一次请求的个数。