当前位置: 首页 > ds >正文

文件(分片)并行上传时计算总的上传进度

1. 基于已上传字节数计算

<template><input type="file" multiple @change="uploadFiles" /><div>总进度:{{ totalProgress }}%</div>
</template><script>
export default {data() {return {totalProgress: 0,filesProgress: {}, // 存储每个文件的上传进度 { filename: percentage }}},methods: {async uploadFiles(e) {const files = e.target.files;if (!files.length) return;// 初始化进度记录this.filesProgress = {};Array.from(files).forEach(file => {this.filesProgress[file.name] = 0;});// 并行上传const promises = Array.from(files).map(file => {const formData = new FormData();formData.append('files', file);return axios.post('/upload', formData, {onUploadProgress: (progressEvent) => {// 更新单个文件进度this.filesProgress[file.name] = Math.round((progressEvent.loaded / progressEvent.total) * 100);// 计算总进度this.calculateTotalProgress();}});});await Promise.all(promises);},calculateTotalProgress() {const progresses = Object.values(this.filesProgress);const total = progresses.reduce((sum, p) => sum + p, 0);this.totalProgress = Math.round(total / progresses.length);}}
}
</script>

原理:
为每个文件维护独立的进度(0-100)
实时计算所有文件进度的平均值

2. 基于已上传文件数计算(适合等大小文件)

data() {return {uploadedCount: 0,totalFiles: 0}
},
methods: {async uploadFiles(e) {const files = e.target.files;this.totalFiles = files.length;this.uploadedCount = 0;await Promise.all(files.map(file => {return axios.post('/upload', file).then(() => {this.uploadedCount++;this.totalProgress = Math.round((this.uploadedCount / this.totalFiles) * 100);});}));}
}

适用场景:当所有文件大小相近时更高效,实际计算的上传文件数占总数的比

3. 精确字节级计算

data() {return {totalSize: 0,       总字节数prevLoadedMap: {}, // 存储 { 文件名: 上次loaded值 }uploadedSize: 0,   // 总已上传字节数}
},
methods: {
getPrevLoaded(filename) {return this.prevLoadedMap[filename] || 0;},savePrevLoaded(filename, loaded) {this.prevLoadedMap[filename] = loaded;},async uploadFiles(e) {const files = e.target.files;// 计算总大小this.totalSize = Array.from(files).reduce((sum, file) => sum + file.size, 0);this.uploadedSize = 0;const promises = files.map(file => {const formData = new FormData();formData.append('file', file);return axios.post('/upload', formData, {onUploadProgress: (progressEvent) => {// 累加已上传字节数this.uploadedSize += progressEvent.loaded - this.getPrevLoaded(file.name);this.savePrevLoaded(file.name, progressEvent.loaded);this.totalProgress = Math.round((this.uploadedSize / this.totalSize) * 100);}});});await Promise.all(promises);}
}
  1. progressEvent.loaded 的特性
    progressEvent.loaded 表示 当前文件已上传的字节数。
    在文件上传过程中,这个值会通过多次回调递增(例如从 0 → 500KB → 1MB → 完整文件大小)。
    问题:如果直接累加 progressEvent.loaded,会导致重复计算(例如第一次+500KB,第二次+1MB,实际只新增了500KB,但会错误累加1MB)。
  2. 解决重复累加的关键
    this.getPrevLoaded(file.name)
    获取该文件上一次回调时的 loaded 值(初始为0)。
    progressEvent.loaded - this.getPrevLoaded(file.name)
    计算出本次回调新增的字节数(正确的增量)。
    this.savePrevLoaded(file.name, progressEvent.loaded)
    保存当前 loaded 值,供下一次回调使用。

需要记录每个文件上次已上传的字节数
适用于文件大小差异大的场景

http://www.xdnf.cn/news/5553.html

相关文章:

  • 如何在Unity中进行四舍五入
  • Apache Ranger 2.2.0 编译
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3/R1商用服务开通教程以及模型体验
  • TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题
  • Python-MCPInspector调试
  • STC-ISP烧录过程中显示“正在检测目标单片机...”
  • 基于Flask、Bootstrap及深度学习的水库智能监测分析平台
  • 闲鱼智能客服机器人-实现闲鱼平台7×24小时自动化值守
  • # 2-STM32-复位和时钟控制RCC
  • MySql(基础)
  • spark:map 和 flatMap 的区别(Scala)
  • CentOS7离线安装Mysql8
  • 分治算法
  • K8S cgroups详解
  • 【Bluedroid】蓝牙HID DEVICE断开连接流程源码分析
  • 【android bluetooth 框架分析 02】【Module详解 5】【HciLayer 模块介绍】
  • Python3安装HTMLTestRunner
  • 企业内训|智能调控系统算法与优化——某汽车厂商
  • 如何反向绘制出 .NET程序 异步方法调用栈
  • 设计模式学习整理
  • 自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例
  • 多空短线决策+飞云分仓操盘,两个副图指标组合操盘技术,短线更精准有效
  • 华为IP(6)
  • 嵌入式硬件篇---SPI
  • 虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系
  • #微调重排序模型:Reranking从入门到实践
  • 医院药品管理系统(准备工作)
  • 元数据和主数据
  • 从代码学习深度学习 - 转置卷积 PyTorch版
  • Oracle 通过 ROWID 批量更新表