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

并行发起http请求

1. 使用 axios + Promise.all

<template><input type="file" multiple @change="handleFileUpload" />
</template><script>
import axios from 'axios';export default {methods: {async handleFileUpload(event) {const files = event.target.files;if (!files.length) return;try {// 并行上传所有文件const uploadPromises = Array.from(files).map(file => {const formData = new FormData();formData.append('file', file); // 后端接收的字段名可能是 'file'return axios.post('/api/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' },});});// 等待所有请求完成const results = await Promise.all(uploadPromises);console.log('所有文件上传成功:', results.map(res => res.data));} catch (error) {console.error('上传失败:', error);}},},
};
</script>

FormData 用于构造文件上传请求。
Promise.all 并行发起多个上传请求。
headers: { ‘Content-Type’: ‘multipart/form-data’ } 必须设置,否则后端可能无法正确解析文件。

2. 使用 fetch + async/await

如果不依赖 axios,可以使用原生 fetch 实现

async function uploadFiles(files) {try {const uploadPromises = Array.from(files).map(file => {const formData = new FormData();formData.append('file', file);return fetch('/api/upload', {method: 'POST',body: formData,// fetch 默认会自动设置 multipart/form-data});});const responses = await Promise.all(uploadPromises);const results = await Promise.all(responses.map(res => res.json()));console.log('上传结果:', results);} catch (error) {console.error('上传失败:', error);}
}

3. 限制并发上传数量(避免服务器压力过大)

如果同时上传大量文件(如 100+),可以使用 p-limit 控制并发数。

import pLimit from 'p-limit';const limit = pLimit(3); // 最多同时上传3个文件async function uploadWithLimit(files) {try {const uploadPromises = files.map(file => limit(() => {const formData = new FormData();formData.append('file', file);return axios.post('/api/upload', formData);}));const results = await Promise.all(uploadPromises);console.log('上传成功:', results);} catch (error) {console.error('上传失败:', error);}
}

大文件批量上传(如云盘应用)。
避免浏览器或服务器因并发过高而崩溃

4. 显示上传进度

如果需要显示每个文件的上传进度,可以使用 axios 的 onUploadProgress

const uploadPromises = files.map(file => {const formData = new FormData();formData.append('file', file);return axios.post('/api/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' },onUploadProgress: progressEvent => {const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);console.log(`${file.name} 上传进度: ${percent}%`);// 可以更新 Vue 的 data 或 store 来显示进度条},});
});await Promise.all(uploadPromises);

取消请求:

如果用户离开页面,可以使用 axios.CancelToken 或 AbortController 取消未完成的请求,避免内存泄漏。

如果希望即使某些文件上传失败,也能继续处理成功的文件,可以使用 Promise.allSettled

<template><div><input type="file" multiple @change="handleFileUpload" /><div v-if="uploading">上传中... {{ progress }}%</div><div v-for="(result, index) in results" :key="index">文件 {{ index + 1 }}: {{ result.status === 'success' ? '成功' : '失败' }}</div></div>
</template><script>
import axios from 'axios';export default {data() {return {uploading: false,progress: 0,results: [],};},methods: {async handleFileUpload(event) {const files = event.target.files;if (!files.length) return;this.uploading = true;this.results = [];try {const uploadPromises = Array.from(files).map(file => {const formData = new FormData();formData.append('file', file);return axios.post('/api/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' },onUploadProgress: progressEvent => {this.progress = Math.round((progressEvent.loaded / progressEvent.total) * 100);},});});const settledResults = await Promise.allSettled(uploadPromises);this.results = settledResults.map(result => ({status: result.status === 'fulfilled' ? 'success' : 'error',data: result.status === 'fulfilled' ? result.value.data : result.reason,}));} catch (error) {console.error('上传出错:', error);} finally {this.uploading = false;}},},
};
</script>

相关文章:

  • Python Cookbook-7.9 访问 MySQL 数据库
  • python实现用户登录
  • 【锂电池剩余寿命预测】SVM支持向量机锂电池剩余寿命预测(Pytorch完整源码和数据)
  • AAAI-2025 | 电子科大类比推理助力精准识别!SPAR:基于自提示类比推理的无人机目标探测技术
  • HttpServletResponse的理解
  • 【第35节 数据库设计】
  • 大模型对时尚穿搭体验的革新与重塑
  • Linux为啥会重新设置中断请求号与中断向量号之间的关系?
  • 数字化工厂中央控制室驾驶舱系统架构文档
  • Pandas进行json_normalize多层嵌套Json数据展平
  • 王道计算机网络知识点总结
  • 【运维】基于Python打造分布式系统日志聚合与分析利器
  • 优化审核模块响应时间从8s降至1.2s的数据库解决方案
  • leetcode 454. 4Sum II
  • 【Python-Day 12】Python列表进阶:玩转添加、删除、排序与列表推导式
  • 机器人手臂“听不懂“指令?Ethercat转PROFINET网关妙解通信僵局
  • 【GPT入门】第38课 RAG评估指标概述
  • 【办公类-39-07】20250511批量生成通义万相图片(七)彩色背景蝴蝶-筛选无黑无白的图片
  • 【Bluedroid】蓝牙HID DEVICE断开连接流程源码分析
  • 基于Java和高德开放平台的WebAPI集成实践-以搜索POI2.0为例
  • 香港根据《维护国家安全条例》订立附属法例
  • 警方通报:某博主遭勒索后自杀系自导自演,已立案调查
  • 老人将房产遗赠给外孙,三个女儿却认为遗嘱应无效,法院判了
  • 中国工程院院士、国医大师、现代中国针灸奠基人石学敏逝世
  • “犍陀罗艺术与亚洲文明”在浙大对外展出
  • 阚吉林任重庆市民政局党组书记,原任市委组织部主持日常工作的副部长