vue实现请求加锁
Vue 实现请求加锁的方法
在 Vue 中实现请求加锁可以防止重复请求,提升应用性能和用户体验。以下是几种常见的方法:
使用布尔标志位控制请求状态
在组件或 Store 中定义一个布尔变量,标记当前请求状态。发起请求前检查该标志位,请求结束后重置。
data() {
return {
isRequesting: false
}
},
methods: {
async fetchData() {
if (this.isRequesting) return
this.isRequesting = true
try {
const res = await api.getData()
// 处理响应
} finally {
this.isRequesting = false
}
}
}
使用 axios 拦截器实现全局锁
通过 axios 的请求/响应拦截器实现全局请求锁,适用于需要统一管理的场景。
let pendingRequests = 0
const MAX_CONCURRENT = 3
axios.interceptors.request.use(config => {
if (pendingRequests >= MAX_CONCURRENT) {
return Promise.reject(new Error('Too many requests'))
}
pendingRequests++
return config
})
axios.interceptors.response.use(
response => {
pendingRequests--
return response
},
error => {
pendingRequests--
return Promise.reject(error)
}
)
基于 Promise 的请求队列
创建一个请求队列管理系统,确保同一时刻只有一个相同请求在执行。
const requestMap = new Map()
async function lockedRequest(key, fn) {
if (requestMap.has(key)) {
return requestMap.get(key)
}
const promise = fn()
requestMap.set(key, promise)
try {
return await promise
} finally {
requestMap.delete(key)
}
}
// 使用示例
lockedRequest('user-data', () => api.getUserData())
使用装饰器模式(Vue + TS)
在 TypeScript 项目中可以使用装饰器封装请求方法。
function lockRequest(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value
let isLocked = false
descriptor.value = async function(...args: any[]) {
if (isLocked) return
isLocked = true
try {
return await originalMethod.apply(this, args)
} finally {
isLocked = false
}
}
}
// 使用示例
class ApiService {
@lockRequest
async fetchData() {
return axios.get('/api/data')
}
}
使用第三方库
考虑使用专门处理并发控制的库如 p-limit:
import pLimit from 'p-limit'
const limit = pLimit(1) // 同时只允许1个请求
async function safeFetch() {
return limit(() => fetch('/api'))
}
选择哪种方法取决于具体需求:

- 组件级控制适合局部场景
- 拦截器适合全局控制
- 请求队列适合复杂并发管理
- 装饰器适合TS项目
- 第三方库提供现成解决方案






