js - H5 上传(FE 部分)

复制代码
async function action(file) {
  const fileHash = await computedFileHash(file);
  const chunks = createChunks(file, {
    chunkSize: 1024 * 10,
    fileHash
  });
}

/**
 * 文件切片群上传
 * 
 * @param {Object} chunks 文件切片群
 */
function uploadChunks(chunks, maxRequest = 6) {
  return new Promise((resolve, reject) => {
    if (!chunks.length) resolve([]);

    let requestSliceArr = [];
    let start = 0;
    let index = 0;
    let requestResults = [];
    let requestErrResults = [];

    while(start < chunks.length) {
      const stop = start + maxRequest;

      requestSliceArr.push(chunks.slice(start, stop));
      start = stop;
    }

    const request = async () => {
      if (index > requestSliceArr.length - 1) return resolve(requestResults);

      let sliceChunks = requestSliceArr[index++];

      Promise.all(sliceChunks.map(chunk => uploadHandler(chunk)))
        .then(res => {
          requestResults.push(...(Array.isArray(res) ? res : []));
          request(); // 循环调用
        })
        .catch((err) => {
          requestErrResults.push(...(Array.isArray(err) ? err : []))
          reject(requestErrResults);
      })
    }

  })
}

/**
 * 单个文件切片上传逻辑
 * 
 * @param {Object} chunk 文件切片
 */
function uploader(chunk, url) {
  return new Promise((resolve, reject) => {
    const fd = new FormData();
    const { file, fileHash, chunkIndex } = chunk;

    fd.append('file', file);
    fd.append('fileHash', fileHash);
    fd,append('chunkIndex', chunkIndex);

    fetch(url, {
      method: 'POST',
      body: fd,
    }).then(res => {
      chunk.uploaded = true;
      resolve(res.json());
    }).catch(err => reject(err));
  });
}

const defaultChunkOptions = {
  chunkSize: 1024 * 1024 * 1,
}

function createChunks(file, options = defaultChunkOptions) {
  const _opts = {
    ...defaultChunkOptions,
    ...options,
  };
  const { chunkSize, fileHash } = _opts;
  const chunks = [];
  let start = index = 0;

  while (start < file.size) {
    const stop = start + chunkSize;
    const currentChunk = file.slice(start, stop);

    chunks.push({
      file: currentChunk,
      uploaded: false,
      chunkIndex: index++,
      fileHash
    });
    start = stop;
  }

  return chunks;
}

// -------------- utils --------------
function computedFileHash(file) {
  return new Promise((resolve) => {
    const fileReader = new FileReader();

    fileReader.onload = e => {
      resolve(SparkMD5.ArrayBuffer.hash(e.target.result));
    };
    fileReader.readAsArrayBuffer(file);
  })
}
复制代码

 

posted @   shiweiqianju  阅读(3)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示