如何在前端循环调取接口,实时查询数据

一: 最简单:setInterval 轮询

复制代码
<template>
  页面内容

</template>

<script setup>
import { onMounted, onUnmounted } from 'vue'
import axios from 'axios'

let timer = null

const fetchData = async () => {
  const res = await axios.get('/api/data')
  console.log(res.data)
}

onMounted(() => {
  fetchData() // 先请求一次
  timer = setInterval(fetchData, 5000) // 每5秒轮询
})

onUnmounted(() => {
  clearInterval(timer) // 组件销毁清除
})
</script>
<style src="./index.scss" lang="scss" scoped></style>

缺点:

1.如果接口慢,会请求堆积

2.可能同时发多个请求(还没返回又发新的)

二:推荐:setTimeout + 递归(更安全)

复制代码
<template>
  页面内容

</template>

<script setup>
import { onMounted, onUnmounted } from 'vue'
import axios from 'axios'

let timer = null
let isRunning = true

const loopFetch = async () => {
  if (!isRunning) return

  try {
    const res = await axios.get('/api/data')
    console.log(res.data)
  } catch (e) {
    console.error(e)
  }

  timer = setTimeout(loopFetch, 5000) // 等本次结束再发下一次
}

onMounted(() => {
  loopFetch()
})

onUnmounted(() => {
  isRunning = false
  clearTimeout(timer)
})



</script>
<style src="./index.scss" lang="scss" scoped></style>

优点:不会并发

三:WebSocket(真正实时)

复制代码
const ws = new WebSocket('ws://localhost:8080')

ws.onmessage = (event) => {
  console.log('实时数据:', event.data)
}

优点:

1.服务端推送(不需要轮询)

2.真·实时

缺点:需要后端支持

Server-Sent Events(SSE)

复制代码
const eventSource = new EventSource('/api/stream')

eventSource.onmessage = (event) => {
  console.log(event.data)
}

如果是由vue3+vite的项目,可以使用下面方法

四:自己封装 usePolling

新建usePolling.js

复制代码
// usePolling.js
import { ref, onUnmounted } from 'vue'

export function usePolling(fn, interval = 3000) {
  const timer = ref(null)
  const isRunning = ref(false)

  const start = async () => {
    if (isRunning.value) return
    isRunning.value = true

    const loop = async () => {
      if (!isRunning.value) return

      await fn()
      timer.value = setTimeout(loop, interval)
    }

    loop()
  }

  const stop = () => {
    isRunning.value = false
    clearTimeout(timer.value)
  }

  onUnmounted(stop)

  return {
    start,
    stop,
    isRunning
  }
}

调用usePolling.js

复制代码
<template>
  页面内容

</template>

<script setup>
import { usePolling } from '@/hooks/usePolling'
import axios from 'axios'

const fetchData = async () => {
  const res = await axios.get('/api/data')
  console.log(res.data)
}

const { start, stop } = usePolling(fetchData, 5000)

onMounted(() => {
  start()
})

</script>
<style src="./index.scss" lang="scss" scoped></style>

优点:

1.自动避免并发

2.自动清理

3.可随时暂停/恢复

4.可复用

五:用 VueUse(强烈推荐 ⭐⭐⭐)

1.用 useIntervalFn(简单轮询)

Bash

复制代码
npm install @vueuse/core

import { useIntervalFn } from '@vueuse/core'
import axios from 'axios'

const { pause, resume } = useIntervalFn(async () => {
  const res = await axios.get('/api/data')
  console.log(res.data)
}, 5000)

2.更推荐:useTimeoutFn(避免并发)

复制代码
import { useTimeoutFn } from '@vueuse/core'

const loop = async () => {
  await axios.get('/api/data')
  start()
}

const { start, stop } = useTimeoutFn(loop, 5000)

VueUse优势:

1.自动处理生命周期

2.API 很优雅

3.和 Vue3 完全契合

4.内置暂停/恢复

六:用请求库 TanStack Query(Vue Query)

Bash

复制代码
npm install @tanstack/vue-query

import { useQuery } from '@tanstack/vue-query'
import axios from 'axios'

const { data } = useQuery({
  queryKey: ['data'],
  queryFn: () => axios.get('/api/data'),
  refetchInterval: 5000 // 自动轮询
})

优点(很强):

1.自动轮询

2.缓存

3.防抖

4.请求去重

5.错误重试

6.loading 状态

相关推荐
yujunl1 小时前
U9的UI插件客开的总结1
开发语言
Hilaku1 小时前
从搜索排名到 AI 回答? 先聊一聊 AI 可见度工具 BuildSOM !
前端·javascript·程序员
zzmgc41 小时前
纯静态 + Web Worker + 虚拟滚动:我是怎么让浏览器吃下 10MB JSON 不卡的
前端·架构
辰同学ovo1 小时前
用 Chrome DevTools MCP 给 AI 写的页面做“质检“
前端·人工智能·chrome devtools
多敲代码防脱发1 小时前
Spring进阶(容器实现)
java·开发语言·后端·spring
乌托邦1 小时前
uni-mini-ci:让 uniapp 小程序构建后自动预览和上传
前端·vue.js·uni-app
豹哥学前端1 小时前
前端工程化实战:从包管理到 Vite 配置,一套下来全明白
前端·javascript·vite
小新同学^O^2 小时前
简单学习 --> 模型微调
开发语言·人工智能·python·模型微淘
网安小白2 小时前
如果解决github域名解析问题
前端