You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制Google Drive异步断点续传的并发上传数量?

解决Google Drive分片上传并发控制问题

你不需要修改外部的resumableupload_js.min.js,只需要调整自己的上传逻辑,通过串行处理批次+Promise监听上传完成来实现每次仅并发10个文件,完成一批再启动下一批。

核心修改点:

  • 放弃原来的for循环直接启动所有批次,改用递归函数串行处理每个批次
  • 将单个文件的上传过程包装为Promise,通过Promise.all监听整个批次的上传完成状态
  • 只有当前批次的所有文件上传完成后,才启动下一个批次的上传

修改后的完整代码:

<input type="file" id="file" multiple="true" />
<input type="button" onclick="run()" value="Upload" />
<div id="progress"></div>

<script src="https://cdn.jsdelivr.net/gh/tanaikech/ResumableUploadForGoogleDrive_js@master/resumableupload_js.min.js"></script>
<script>
function run() {
  google.script.run.withSuccessHandler(accessToken => ResumableUploadForGoogleDrive(accessToken)).getAuth();
}

function ResumableUploadForGoogleDrive(accessToken) {
  const f = document.getElementById("file");
  const chunkSize = 10;
  const files = Array.from(f.files);
  const totalChunks = Math.ceil(files.length / chunkSize);
  
  // 递归处理批次的函数
  async function processBatch(batchIndex) {
    if (batchIndex >= totalChunks) return; // 所有批次处理完成
    
    const startIndex = batchIndex * chunkSize;
    const endIndex = startIndex + chunkSize;
    const currentBatch = files.slice(startIndex, endIndex);
    
    console.log(`开始处理第${batchIndex+1}批,共${currentBatch.length}个文件`);
    
    // 将每个文件的上传包装为Promise
    const uploadPromises = currentBatch.map((file, idx) => {
      return new Promise((resolve, reject) => {
        if (!file) return resolve();
        
        let fr = new FileReader();
        fr.fileName = file.name;
        fr.fileSize = file.size;
        fr.fileType = file.type;
        fr.readAsArrayBuffer(file);
        
        fr.onload = e => {
          var id = "p" + (startIndex + idx + 1);
          var div = document.createElement("div");
          div.id = id;
          document.getElementById("progress").appendChild(div);
          document.getElementById(id).innerHTML = "Initializing.";
          
          const resource = { 
            fileName: fr.fileName, 
            fileSize: fr.fileSize, 
            fileType: fr.fileType, 
            fileBuffer: fr.result, 
            accessToken: accessToken, 
            folderId: "<insert folder ID>" 
          };
          
          const ru = new ResumableUploadToGoogleDrive();
          ru.Do(resource, function (res, err) {
            if (err) {
              console.error(err);
              document.getElementById(id).innerText = `上传失败 (${fr.fileName})`;
              return reject(err);
            }
            
            let msg = "";
            if (res.status == "Uploading") {
              msg = Math.round((res.progressNumber.current / res.progressNumber.end) * 100) + "% (" + fr.fileName + ")";
            } else {
              msg = res.status + " (" + fr.fileName + ")";
              if (res.status === "Done") {
                resolve(); // 只有上传完成时才resolve Promise
              }
            }
            document.getElementById(id).innerText = msg;
          });
        };
        
        fr.onerror = () => {
          reject(new Error(`读取文件失败: ${file.name}`));
        };
      });
    });
    
    // 等待当前批次所有文件上传完成
    await Promise.all(uploadPromises);
    console.log(`第${batchIndex+1}批处理完成`);
    
    // 处理下一个批次
    await processBatch(batchIndex + 1);
  }
  
  // 启动第一个批次
  processBatch(0).catch(err => console.error("上传过程出错:", err));
};
</script>

关键逻辑说明:

  1. Promise包装上传:每个文件的上传流程被包装成Promise,只有当上传状态变为Done时才会resolve,确保能准确监听每个文件的完成事件。
  2. 递归批次处理:processBatch函数负责处理单个批次,通过await Promise.all(uploadPromises)等待当前批次所有文件完成后,再递归调用自身处理下一个批次。
  3. 避免全量并发:取消了原来的for循环直接启动所有批次的逻辑,改为串行触发批次,从根本上控制了并发数为每批10个。

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:42:27