news 2026/8/29 1:52:01

前端上载文件时,上载多个文件,但是一个一个调用接口,怎么实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前端上载文件时,上载多个文件,但是一个一个调用接口,怎么实现

在前端实现多个文件逐个上传,可以通过以下几种方式实现:

1. 使用 async/await 顺序上传

async function uploadFilesSequentially(files) { for (let i = 0; i < files.length; i++) { try { const formData = new FormData(); formData.append('file', files[i]); formData.append('filename', files[i].name); const response = await fetch('/api/upload', { method: 'POST', body: formData }); const result = await response.json(); console.log(`文件 ${files[i].name} 上传成功`, result); // 可以在这里更新上传进度 updateProgress(i + 1, files.length); } catch (error) { console.error(`文件 ${files[i].name} 上传失败:`, error); // 可以选择继续上传剩余文件,或停止上传 // break; // 如果上传失败就停止 } } console.log('所有文件上传完成'); }

2. 使用递归实现顺序上传

function uploadFilesRecursively(files, index = 0) { if (index >= files.length) { console.log('所有文件上传完成'); return Promise.resolve(); } const file = files[index]; const formData = new FormData(); formData.append('file', file); return fetch('/api/upload', { method: 'POST', body: formData }) .then(response => response.json()) .then(result => { console.log(`文件 ${file.name} 上传成功`); updateProgress(index + 1, files.length); // 继续上传下一个文件 return uploadFilesRecursively(files, index + 1); }) .catch(error => { console.error(`文件 ${file.name} 上传失败:`, error); // 可以选择继续上传或停止 return uploadFilesRecursively(files, index + 1); }); }

3. 完整的组件示例

<template> <div> <input type="file" multiple @change="handleFileChange" /> <button @click="uploadFiles">上传文件</button> <!-- 进度显示 --> <div v-if="uploading"> <div>上传进度: {{ uploadedCount }} / {{ totalFiles }}</div> <div>当前文件: {{ currentFileName }}</div> <progress :value="uploadedCount" :max="totalFiles" ></progress> </div> </div> </template> <script setup> import { ref } from 'vue'; import axios from 'axios'; const files = ref([]); const uploading = ref(false); const uploadedCount = ref(0); const totalFiles = ref(0); const currentFileName = ref(''); // 处理文件选择 const handleFileChange = (event) => { files.value = Array.from(event.target.files); }; // 顺序上传文件 const uploadFiles = async () => { if (!files.value.length) return; uploading.value = true; uploadedCount.value = 0; totalFiles.value = files.value.length; for (let i = 0; i < files.value.length; i++) { const file = files.value[i]; currentFileName.value = file.name; try { await uploadSingleFile(file); uploadedCount.value++; } catch (error) { console.error(`文件 ${file.name} 上传失败:`, error); // 可以在这里处理错误,比如记录失败的文件 } } uploading.value = false; console.log('所有文件上传完成'); }; // 上传单个文件 const uploadSingleFile = async (file) => { const formData = new FormData(); formData.append('file', file); formData.append('timestamp', Date.now()); // 可以添加其他参数 formData.append('userId', '123'); formData.append('category', 'documents'); const response = await axios.post('/api/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' }, // 显示上传进度(可选) onUploadProgress: (progressEvent) => { const percent = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); console.log(`文件 ${file.name} 上传进度: ${percent}%`); } }); return response.data; }; </script>

4. 使用 Promise.reduce 实现顺序执行

import axios from 'axios'; async function sequentialUpload(files) { const results = await files.reduce(async (previousPromise, file, index) => { const previousResults = await previousPromise; console.log(`开始上传第 ${index + 1} 个文件: ${file.name}`); try { const formData = new FormData(); formData.append('file', file); const response = await axios.post('/api/upload', formData); previousResults.push({ file: file.name, success: true, data: response.data }); } catch (error) { previousResults.push({ file: file.name, success: false, error: error.message }); } return previousResults; }, Promise.resolve([])); return results; }

5. 并发控制(推荐)

如果需要兼顾效率和顺序,可以使用并发控制:

class FileUploader { constructor(maxConcurrent = 1) { this.maxConcurrent = maxConcurrent; // 最大并发数 this.queue = []; this.activeCount = 0; this.results = []; } addFile(file) { this.queue.push(file); } async uploadAll() { const batches = []; // 将文件分批 for (let i = 0; i < this.queue.length; i += this.maxConcurrent) { batches.push(this.queue.slice(i, i + this.maxConcurrent)); } // 按批次顺序执行 for (const batch of batches) { const batchPromises = batch.map(file => this.uploadSingle(file)); const batchResults = await Promise.allSettled(batchPromises); this.results.push(...batchResults); } return this.results; } async uploadSingle(file) { const formData = new FormData(); formData.append('file', file); return axios.post('/api/upload', formData); } } // 使用示例 const uploader = new FileUploader(3); // 最多3个并发 files.forEach(file => uploader.addFile(file)); uploader.uploadAll().then(results => { console.log('上传结果:', results); });

关键注意事项:

  1. 错误处理:每个文件上传都应该有独立的错误处理

  2. 进度反馈:给用户显示上传进度

  3. 取消上传:提供取消上传的功能

  4. 重试机制:对失败的上传提供重试功能

  5. 性能优化:大文件可以考虑分片上传

  6. 内存管理:及时释放不再需要的文件对象

选择哪种方案取决于你的具体需求:

  • 如果需要严格的顺序执行,使用方案1或2

  • 如果需要更好的性能,可以使用方案5的并发控制

  • 如果需要在Vue/React中使用,可以结合框架的特性

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 9:09:39

Kimi生成的内容AI率太高?2026年降AI工具红黑榜

Kimi生成的内容AI率太高&#xff1f;2026年降AI工具红黑榜 TL;DR&#xff1a;Kimi写的内容AI率高是正常现象&#xff0c;毕竟它就是个AI。想降低AI率&#xff0c;Kimi自己改写效果有限&#xff08;改完还是AI&#xff09;&#xff0c;专业降AI工具效果更好。红榜推荐&#xff1…

作者头像 李华
网站建设 2026/8/27 15:08:32

手机上写代码、做PPT、分析Excel?这款“AI 全能工作台“让我随时随地都能工作

躺在沙发上刷手机的时候突然想改个 bug&#xff0c;结果发现电脑在书房懒得动……周末突然想起老板周一要的 PPT 还没做……相信每个打工人都有过这种时刻。今天给大家介绍一个我自己做的工具——WebCode&#xff0c;一个能在手机上远程驱动 AI 干活的全能工作台。写代码、做设…

作者头像 李华
网站建设 2026/8/24 18:51:43

学霸同款2026 MBA论文必备TOP10 AI论文平台

学霸同款2026 MBA论文必备TOP10 AI论文平台 2026年MBA论文写作工具测评&#xff1a;为何需要一份权威榜单&#xff1f; 随着人工智能技术的持续发展&#xff0c;越来越多的MBA学生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上五花八门的平台&#xff0c;如何选…

作者头像 李华
网站建设 2026/8/24 0:38:23

医保理赔票据自动识别方案

医保审核、商业健康险理赔、医院财务对账……这些场景中&#xff0c;医疗票据处理一直是令人头疼的难题。全国各地医疗机构出具的票据版式不统一、表格结构复杂、图像质量参差不齐&#xff0c;传统人工录入单张票据耗时5-8分钟&#xff0c;错漏率高达15%。如今&#xff0c;合合…

作者头像 李华
网站建设 2026/8/25 1:00:15

PostgreSQL即时恢复:被内核预留的恢复能力

一、概念澄清&#xff1a;即时恢复的真实定位 1.常见的误解与真相 误解真相"即时恢复挑战备份恢复"即时恢复是备份恢复的对位角色&#xff0c;不是替代"少数专家的非常规技巧"基于PostgreSQL内核设计原则的合理应用"更激进的恢复策略"更理性的…

作者头像 李华
网站建设 2026/8/24 22:13:08

使用 dmesg 工具诊断Linux系统问题基本用法案例

dmesg&#xff08;Diagnostic Message&#xff09;是 Linux 中显示内核环形缓冲区&#xff08;ring buffer&#xff09;内容的强大工具。以下是详细解析&#xff1a; 一、dmesg 基础 作用 显示内核启动信息查看硬件设备检测和驱动加载信息追踪内核级错误和警告诊断系统问题和性…

作者头像 李华