最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
一文分享4种Vue并发控制实战方案
时间:2026-06-08 08:27:33 编辑:袖梨 来源:一聚教程网
在Vue项目开发中,经常会遇到需要同时发起几十个请求的场景(如批量数据查询、批量提交、页面初始化加载多接口数据)。若直接同时发起所有请求,会导致网络拥堵、接口超时、浏览器卡顿,甚至触发后端接口限流,影响用户体验和系统稳定性。本文结合Vue2/Vue3实战,提供4种主流并发控制方案,覆盖不同场景,可直接落地使用,轻松管控几十个请求的并发逻辑。

一、并发控制核心逻辑
并发控制的核心是:限制同一时间发起的请求数量,将几十个请求分批次、有序执行,避免一次性占用过多网络资源。核心要点的2个:
- 控制并发数:根据后端接口承载能力和浏览器限制,合理设置并发数(通常4-6个,过多易拥堵,过少效率低);
- 有序执行:分批次发起请求,上一批请求完成(成功/失败)后,再发起下一批,确保请求有序且不拥堵;
- 异常兼容:处理单个请求失败、超时场景,避免单个请求失败导致整个并发流程中断。
以下方案均适配Vue2/Vue3,基于Axios请求库(Vue项目主流请求工具),可直接复制到项目中修改使用。
二、4种实战并发控制方案(按推荐度排序)
方案一:并发池控制(最推荐,灵活高效,适配所有场景)
核心思路:封装一个并发池工具,将所有请求放入队列,限制同时执行的请求数量,当某个请求完成后,自动从队列中取出下一个请求执行,循环直至所有请求完成。该方案灵活可控,可处理成功/失败回调、超时控制,是几十个请求并发管控的最优选择。
1. 封装并发池工具(Vue2/Vue3通用)
// utils/requestPool.jsimport axios from 'axios';// 极简版并发池(核心功能:限制并发、处理超时、返回结果)export async function requestPool(requestList, limit = 4, timeout = 10000) { const result = []; let running = 0; let queue = [...requestList]; const runRequest = async () => { if (queue.length === 0 && running === 0) return result; while (running < limit && queue.length > 0) { running++; const requestFn = queue.shift(); const index = requestList.length - queue.length - running; try { const res = await Promise.race([ requestFn(), new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), timeout)) ]); result[index] = { success: true, data: res.data }; } catch (error) { result[index] = { success: false, error: error.message }; } finally { running--; await runRequest(); } } }; await runRequest(); return result;}// 极简请求函数(按需修改url和参数)export function createRequestFn(id) { return () => axios({ url: `/api/data/${id}`, method: 'get', timeout: 10000 });}2. Vue组件中使用(Vue3示例,Vue2可直接适配)
<template> <div> <button @click="handleBatchRequest">发起30个并发请求</button> <div class="result">成功:{{ successCount }} 个 | 失败:{{ failCount }} 个</div> </div></template><script setup>import { ref } from 'vue';import { requestPool, createRequestFn } from '@/utils/requestPool';const successCount = ref(0);const failCount = ref(0);// 极简使用示例(30个请求,并发数5)const handleBatchRequest = async () => { const requestList = Array.from({ length: 30 }, (_, i) => createRequestFn(i + 1)); const results = await requestPool(requestList, 5); successCount.value = results.filter(item => item.success).length; failCount.value = results.filter(item => !item.success).length;};</script><style scoped>.result { margin-top: 20px; font-size: 14px; color: #333; }</style>方案一优势与适配场景
- 优势:灵活可控,可自定义并发数、超时时间;单个请求失败不影响整体流程;请求结果顺序与发起顺序一致;代码复用性强,可全局调用。
- 适配场景:几十个请求的批量查询、批量提交、页面初始化多接口加载等所有场景(最推荐)。
方案二:分批次请求(简单易实现,适合对顺序要求高的场景)
核心思路:将几十个请求分成若干批次,每批次发起固定数量的请求(如每批5个),等待当前批次所有请求完成后,再发起下一批。实现简单,无需复杂封装,适合对请求顺序有严格要求的场景(如下一批请求依赖上一批请求结果)。
1. 封装分批次请求工具(Vue2/Vue3通用)
// utils/batchRequest.jsimport axios from 'axios';/** * 分批次请求控制 * @param {Array} requestList - 请求列表(每个元素是请求参数,如id) * @param {Number} batchSize - 每批请求数量(默认5个) * @returns {Promise} - 所有请求结果数组 */export async function batchRequest(requestList, batchSize = 5) { const result = []; // 计算总批次 const totalBatch = Math.ceil(requestList.length / batchSize); // 循环发起每批次请求 for (let i = 0; i < totalBatch; i++) { // 截取当前批次的请求参数 const currentBatch = requestList.slice(i * batchSize, (i + 1) * batchSize); // 发起当前批次的所有请求(并行) const batchResult = await Promise.allSettled( currentBatch.map(id => axios({ url: `/api/data/${id}`, method: 'get', timeout: 10000 }).then(res => ({ success: true, data: res.data })) .catch(err => ({ success: false, error: err.message })) ) ); // 将当前批次结果存入总结果 result.push(...batchResult); } return result;}2. Vue组件中使用
<script setup>import { ref } from 'vue';import { batchRequest } from '@/utils/batchRequest';const successCount = ref(0);const failCount = ref(0);const handleBatchRequest = async () => { // 生成30个请求参数(如id数组) const requestList = Array.from({ length: 30 }, (_, i) => i + 1); // 分批次请求,每批5个 const results = await batchRequest(requestList, 5); // 处理结果 successCount.value = results.filter(item => item.success).length; failCount.value = results.filter(item => !item.success).length;};</script>方案二优势与适配场景
- 优势:实现简单,无需复杂封装;请求批次清晰,顺序可控;适合下一批请求依赖上一批结果的场景。
- 适配场景:对请求顺序有要求、批量提交且需分批校验的场景(如分批提交表单数据,上一批通过再提交下一批)。
方案三:Axios拦截器控制并发(全局管控,适合简单场景)
核心思路:通过Axios的请求拦截器和响应拦截器,维护一个“正在执行的请求”计数器,当计数器达到并发限制时,将后续请求存入队列,等待正在执行的请求完成后,再依次发起。适合简单场景,无需在组件中单独处理,全局统一管控。
1. 全局配置Axios并发控制(Vue2/Vue3通用)
// utils/axiosConfig.jsimport axios from 'axios';// 并发限制数const CONCURRENT_LIMIT = 4;// 正在执行的请求计数器let requestCount = 0;// 请求队列const requestQueue = [];// 创建Axios实例const service = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000});// 请求拦截器:控制并发service.interceptors.request.use( config => { return new Promise(resolve => { // 若当前请求数未达限制,直接发起请求 if (requestCount < CONCURRENT_LIMIT) { requestCount++; resolve(config); } else { // 达到限制,存入请求队列 requestQueue.push(resolve); } }); }, error => { return Promise.reject(error); });// 响应拦截器:请求完成后,从队列中取出下一个请求service.interceptors.response.use( response => { // 请求完成,计数器减1 requestCount--; // 若队列中有请求,取出并执行 if (requestQueue.length > 0) { const resolve = requestQueue.shift(); requestCount++; resolve(service.defaults); } return response; }, error => { // 失败也需计数器减1,避免队列卡住 requestCount--; if (requestQueue.length > 0) { const resolve = requestQueue.shift(); requestCount++; resolve(service.defaults); } return Promise.reject(error); });export default service;2. Vue组件中使用
<script setup>import { ref } from 'vue';import request from '@/utils/axiosConfig';const successCount = ref(0);const failCount = ref(0);// 直接发起30个请求,Axios拦截器自动控制并发const handleBatchRequest = async () => { const requestList = []; for (let i = 1; i <= 30; i++) { requestList.push( request({ url: `/api/data/${i}`, method: 'get' }).then(res => ({ success: true, data: res.data })) .catch(err => ({ success: false, error: err.message })) ); } // 等待所有请求完成 const results = await Promise.allSettled(requestList); successCount.value = results.filter(item => item.success).length; failCount.value = results.filter(item => !item.success).length;};</script>方案三优势与适配场景
- 优势:全局统一管控,组件中无需单独处理并发逻辑;侵入性低,原有请求代码无需修改;实现简单,适合快速落地。
- 适配场景:项目中所有批量请求需统一控制并发、无需个性化并发配置的简单场景。
方案四:使用第三方库(高效快捷,适合复杂场景)
核心思路:借助成熟的第三方库(如p-limit),快速实现并发控制,无需自己封装工具,适合复杂场景(如并发数动态调整、请求优先级控制)。p-limit轻量、易用,是前端并发控制的常用库。
1. 安装与使用(Vue2/Vue3通用)
// 1. 安装依赖// npm install p-limit --save// 2. 组件中使用<script setup>import { ref } from 'vue';import axios from 'axios';import pLimit from 'p-limit';// 设置并发限制数为4const limit = pLimit(4);const successCount = ref(0);const failCount = ref(0);const handleBatchRequest = async () => { // 生成30个请求函数,并用p-limit包装 const requestList = []; for (let i = 1; i <= 30; i++) { // 用limit包装请求函数,限制并发 requestList.push( limit(() => axios({ url: `/api/data/${i}`, method: 'get', timeout: 10000 }).then(res => ({ success: true, data: res.data })) .catch(err => ({ success: false, error: err.message })) ) ); } // 等待所有请求完成 const results = await Promise.allSettled(requestList); successCount.value = results.filter(item => item.success).length; failCount.value = results.filter(item => !item.success).length;};</script>方案四优势与适配场景
- 优势:无需自己封装,高效快捷;支持动态调整并发数、请求优先级;成熟稳定,适配复杂并发场景。
- 适配场景:复杂并发需求(如动态调整并发数、设置请求优先级)、不想自己封装工具的场景。
三、Vue2与Vue3适配差异(关键注意点)
- 请求工具:两者均使用Axios,配置方式完全一致,无差异;
- 组件写法:Vue3使用组合式API(setup语法),Vue2使用选项式API(methods中编写逻辑),核心并发控制逻辑完全一致;
- 环境变量:Vue3使用import.meta.env,Vue2使用process.env,修改Axios baseURL时需注意适配;
- 第三方库:p-limit等库适配所有Vue版本,无差异。
四、避坑指南(高频问题)
- 并发数设置:避免设置过大(如超过10个),否则会导致网络拥堵、后端限流;建议设置4-6个,根据后端接口承载能力调整;
- 超时控制:必须为单个请求设置超时时间,避免某个请求长时间挂起,导致整个并发流程卡住;
- 失败处理:使用Promise.allSettled(而非Promise.all),避免单个请求失败导致整个并发流程中断;
- 请求顺序:并发池和分批次方案可保证请求结果顺序与发起顺序一致,Axios拦截器方案无法保证顺序(需额外处理);
- 内存占用:几十个请求并发时,避免存储过多请求结果,可按需处理结果(如边请求边渲染),减少内存占用。
五、总结
针对Vue中几十个请求的并发控制,4种方案各有适配场景,可根据项目需求灵活选择:
- 并发池控制:最推荐,灵活可控、适配所有场景,兼顾易用性和扩展性;
- 分批次请求:适合对请求顺序有要求、下一批依赖上一批结果的场景;
- Axios拦截器:适合全局统一管控、无需个性化配置的简单场景;
- 第三方库:适合复杂场景、不想自己封装工具的场景。
实际开发中,建议优先使用“并发池控制”方案,既能灵活控制并发数、处理异常,又能保证请求顺序,可直接复制本文代码,修改请求地址和参数即可快速落地,轻松解决几十个请求的并发难题。
以上就是一文分享4种Vue并发控制的实战方案的详细内容,更多关于Vue并发控制的资料请关注本站其它相关文章!