对i请求流控

This commit is contained in:
bob
2025-02-26 21:47:36 +08:00
parent f45d8f91bb
commit b877a62038
2 changed files with 64 additions and 12 deletions

View File

@@ -0,0 +1,31 @@
import { ElMessage } from 'element-plus'
/**
* 流控在duration时间内只允许task任务被执行countLimit次
* @param {*} task 待执行的任务Promise可以是请求或者其他
* @param {*} countLimit 控制数量
* @param {*} duration 控制周期 ms
* @returns
*/
export const flowLimiteWrapper = (task, countLimit, duration) => {
let count = 0
return async () => {
if (count >= countLimit) {
ElMessage.warning('请求太过频繁,请稍后再试')
return Promise.reject(new Error('REQUEST_LIMITED')) // 返回一个拒绝的 Promise
}
count++
setTimeout(() => {
count--
}, duration)
// 执行任务并确保返回 Promise
try {
const result = await task()
return Promise.resolve(result) // 原始任务可能是同步或异步的
} catch (error) {
return Promise.reject(error) // 捕获同步错误并转为 Promise 拒绝
}
}
}

View File

@@ -11,6 +11,7 @@ import {
import { userStore } from '@/stores'
import { generateClientId } from '@/js/utils/common'
import { ElMessage } from 'element-plus'
import { flowLimiteWrapper } from '@/js/utils/flowLimite'
const isRegister = ref(false)
@@ -71,10 +72,7 @@ const userData = userStore()
const register = async () => {
await form.value.validate() // 注册之前预校验
try {
await userVerifyCaptchaService({
id: captchaId.value,
code: formModel.value.captchaCode
})
await verifyCaptchaWrapper()
} catch (error) {
// 触发form表单报错提醒
formModel.value.captchaCode = ''
@@ -126,19 +124,42 @@ const captchaId = ref('')
const captchaImage = ref('')
const switchRegister = () => {
getCaptchaImage()
getCaptchaImageWrapper().catch(() => {
// do nothing
})
isRegister.value = true
}
const getCaptchaImage = () => {
captchaId.value = ''
captchaImage.value = ''
userGetCaptchaService().then(async (res) => {
captchaId.value = res.data.data.id
captchaImage.value = res.data.data.base64
const onClickCaptcha = () => {
getCaptchaImageWrapper().catch(() => {
// do nothing
})
}
// 60s内只能被执行10次
const getCaptchaImageWrapper = flowLimiteWrapper(
async () => {
captchaId.value = ''
captchaImage.value = ''
return userGetCaptchaService().then((res) => {
captchaId.value = res.data.data.id
captchaImage.value = res.data.data.base64
})
},
10,
60000
)
const verifyCaptchaWrapper = flowLimiteWrapper(
async () => {
return userVerifyCaptchaService({
id: captchaId.value,
code: formModel.value.captchaCode
})
},
10,
60000
)
watch(isRegister, () => {
formModel.value = {
account: !isRegister.value && isRemenberMe.value ? userData.user.account : '',
@@ -214,7 +235,7 @@ watch(isRegister, () => {
<img
v-if="captchaImage"
:src="captchaImage"
@click="getCaptchaImage"
@click="onClickCaptcha"
style="cursor: pointer"
/>
<img v-else src="@/assets/gif/loading.gif" style="width: 40px; height: 40px" />