前端React antd 大文件上传

1,058 阅读1分钟

React antd 大文件上传流程的大概梳理

介绍:

使用antd中Upload上传文件过后会得到一个流,而这个流的大小就是文件的大小

image.png

文件切片:

切片完成后就使用上传接口,使用 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值重复文件不用再次上传,上传多个文件需要评分一次请求的个数。