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

vue3 之异步轮训 hook 封装

背景

开发中经常会遇到支付认证等场景,需要轮训接口获取当前的状态

代码

import { onMounted, onUnmounted, readonly, ref } from 'vue'/*** 函数轮训* 场景: 人脸认证,支付等场景*/interface UsePollingOptions<T = any> {maxPollingCount?: number // 最大轮训次数pollingTime?: number // 轮训时间间隔immediate?: boolean // 是否立即执行pollingFn: (...args: any) => Promise<{isEnd: boolean // 是否结束轮训data?: T // 轮训数据}> // 轮训函数onSuccess?: (data: T) => void // 成功回调onError?: (error: any) => void // 失败回调onComplete?: () => void // 失败、成功、超时都会走onTimeout?: () => void // 超时回调
}export function usePolling<T = any>(options: UsePollingOptions<T>) {const maxPollingCount = ref(options.maxPollingCount || 100)const pollingTime = ref(options.pollingTime || 1000)const timer = ref<NodeJS.Timeout | null>(null)const pollingCount = ref(0) // 当前轮训的次数const isLoading = ref(false) // 是否正在加载const error = ref<any>(null) // 错误信息const isPolling = ref(false) // 是否正在轮询/*** 启动轮训*/const polling = async () => {if (isPolling.value) {console.warn('轮询已在进行中,请勿重复启动')return}isPolling.value = trueisLoading.value = trueerror.value = nullpollingCount.value = 0timer.value = setInterval(async () => {if (pollingCount.value >= maxPollingCount.value) {// 超过最大轮训次数isLoading.value = falseoptions.onTimeout?.()options.onComplete?.()stopPolling()return}try {// 每次轮询时动态获取最新参数const res = await options.pollingFn()if (res.isEnd) {// 认证成功或失败时设置 isLoading 为 falseisLoading.value = falseif (res.data !== undefined) {options.onSuccess?.(res.data)}options.onComplete?.()// 结束轮训stopPolling()} else {// 继续轮询时保持 isLoading 为 trueisLoading.value = true}pollingCount.value++}catch (err) {console.error('轮询过程中发生错误:', err)error.value = err// 认证失败时设置 isLoading 为 falseisLoading.value = falseoptions.onError?.(err)options.onComplete?.()stopPolling()}}, pollingTime.value)}/*** 停止轮训*/const stopPolling = () => {if (timer.value) {clearInterval(timer.value)timer.value = null}isPolling.value = falseisLoading.value = false}/*** 重置轮训*/const resetPolling = () => {stopPolling()pollingCount.value = 0error.value = nullisLoading.value = false}onMounted(() => {if (options.immediate) {polling()}})onUnmounted(() => {stopPolling()})return {polling,stopPolling,resetPolling,isLoading,isPolling,error,pollingCount: readonly(pollingCount), // 当前轮训的次数}
}

组件中使用

const { polling, isLoading } = usePolling<FaceAuthPollResult>({maxPollingCount: 3,pollingTime: 2000,pollingFn: async () => {const res = await userAPI.pollFaceAuthResult({params: { businessId: businessId.value },})if (res.status === 0) {return {isEnd: res.data.isEnd,data: res.data,}}return {isEnd: true,}},onSuccess: (data) => {if (data.success) {message.success('认证成功')visible.value = false} else {message.error(data.msg || '认证失败')}},onTimeout() {message.error('认证超时')},
})const start = () => {polling()
}
http://www.dtcms.com/a/353954.html

相关文章:

  • 深度解析BiTGAN:基于双向Transformer生成对抗网络的长期人体动作预测
  • S 3.1深度学习--卷积神经网络
  • JavaScript工厂模式
  • 鸿蒙、安卓系统如何体验谷歌服务?实用方法分享
  • LangGraph - API多种访问方式
  • Docker 入门指南:从基础概念到常见命令及高级工具详解
  • Transformer 模型详解
  • [Sync_ai_vid] 唇形同步评判器 | 图像与视频处理器 | GPU测试
  • 为什么 “int ” 会变成 “int”?C++ 引用折叠的原理与本质详解
  • nacos2.4.1版本开启鉴权
  • SmartMediakit视角构建低空经济的超低延迟视频基础设施
  • git学习 分支管理(branching)合并分支
  • 鸿蒙清楚本地缓存
  • AI大语言模型助力:国自然/省级基金项目撰写(如何高效准备申请材料?如何精准把握评审标准?从申请者和评审者的不同角度全解
  • 【单例模式】
  • CUDA的编译与调试
  • Mac 上录制视频有几种常见方式
  • 基于springboot的校园资料分享平台(源码+论文+PPT答辩)
  • 网络安全监控中心
  • 【笔记】Windows 安装 Triton 的工作记录(之二)
  • IDR的RWA金融逻辑RWA:全球金融革命的底层协议
  • 数学建模——马尔科夫链(Markov Chain Model)
  • 集成学习之 Stacking(堆叠集成)
  • django配置多个app使用同一个static静态文件目录
  • 使用openCV(C ++ / Python)的Alpha混合
  • 【高级机器学习】 2. Loss Functions(损失函数)
  • 一、快速掌握Python 中的文件操作知识体系
  • mysql zip包安装步骤
  • 2025(秋)中国国际健康产业(成都)博览会:探索健康未来辉煌
  • TCP 并发服务器构建