Skip to content

首先对文件进行切片,传入一个file对象,file对象继承了blob(/blab/)的slice(/slais/)方法,使用它对文件按指定大小进行切割获得blob切片数组。

js
const createFileChunk = (file: UploadRawFile, size = CHUNKSIZE) => {
  const fileChunkList = []
  let cur = 0
  while (cur < file.size) {
    fileChunkList.push({
      file: file.slice(cur, cur + size)
    })
    cur += size
  }
  return fileChunkList
}

针对文件生成唯一标识,使用spark-md5(/spa:rk/)生成hash。考虑到这一步将占用大量资源,阻塞主线程。因此在web worker中进行这个操作

调用初始化上传接口,请求参数是切片数,文件hash。返回taskId

调用切片上传接口,入参切片序号,taskId,请求体里文件切片(formData),返回成功,更新上传进度

但是浏览器限制并发请求的个数,如果使用promise.all一次性的并发请求太多可能导致请求直接失败,使用p-limit帮助我们解决限制并发个数的问题

优化:

秒传,在初始化上传接口中如果后端根据hash发现文件已经存在,则会返回一个特殊的状态码表示该文件已存在

断点上传,调用初始化上传接口,如果没有上传完,返回缺失的切片序号,前端再补充上传缺失的切片即可

暂停上传,axios提供的AbortController取消上传

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// 取消请求
controller.abort()

恢复上传,已知已上传成功列表,只需要上传除此之外的切片