vue实现请求加锁
请求加锁的实现方法
在Vue中实现请求加锁通常是为了防止重复提交或并发请求导致的数据不一致问题。以下是几种常见的实现方式:
使用标志位控制请求状态
通过一个布尔值标志位来控制请求的发送状态:
data() {
return {
isRequesting: false
}
},
methods: {
async fetchData() {
if (this.isRequesting) return
this.isRequesting = true
try {
const response = await axios.get('/api/data')
// 处理响应
} catch (error) {
// 处理错误
} finally {
this.isRequesting = false
}
}
}
使用axios拦截器实现全局锁
通过axios的请求和响应拦截器实现全局请求锁:
// 在axios配置中
let pendingRequests = 0
axios.interceptors.request.use(config => {
if (pendingRequests > 0) {
return Promise.reject(new Error('请求被锁定'))
}
pendingRequests++
return config
})
axios.interceptors.response.use(
response => {
pendingRequests--
return response
},
error => {
pendingRequests--
return Promise.reject(error)
}
)
基于Promise的请求队列
创建一个请求队列来管理并发请求:
const requestQueue = []
let isProcessing = false
async function processQueue() {
if (isProcessing || requestQueue.length === 0) return
isProcessing = true
const request = requestQueue.shift()
try {
const response = await request.fn()
request.resolve(response)
} catch (error) {
request.reject(error)
} finally {
isProcessing = false
processQueue()
}
}
function lockedRequest(fn) {
return new Promise((resolve, reject) => {
requestQueue.push({ fn, resolve, reject })
processQueue()
})
}
// 使用方式
lockedRequest(() => axios.get('/api/data'))
使用Vuex管理请求状态
对于大型应用,可以使用Vuex集中管理请求状态:
// store.js
const store = new Vuex.Store({
state: {
activeRequests: 0
},
mutations: {
startRequest(state) {
state.activeRequests++
},
endRequest(state) {
state.activeRequests--
}
},
getters: {
isRequesting: state => state.activeRequests > 0
}
})
// 组件中使用
computed: {
...mapGetters(['isRequesting'])
},
methods: {
async fetchData() {
if (this.isRequesting) return
this.$store.commit('startRequest')
try {
const response = await axios.get('/api/data')
// 处理响应
} catch (error) {
// 处理错误
} finally {
this.$store.commit('endRequest')
}
}
}
使用防抖函数控制请求频率
对于频繁触发的事件,可以使用防抖函数:
import { debounce } from 'lodash'
methods: {
fetchData: debounce(async function() {
try {
const response = await axios.get('/api/data')
// 处理响应
} catch (error) {
// 处理错误
}
}, 1000)
}
以上方法可以根据具体需求选择或组合使用,实现不同粒度的请求控制。







