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

一: 最简单: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 状态

相关推荐
想吃火锅10052 小时前
【leetcode】405.数字转换为十六进制数js
开发语言·javascript·ecmascript
专注VB编程开发20年2 小时前
AI 生成C# WinForm 窗体 = 目前就是垃圾
开发语言·人工智能·c#
cfm_29142 小时前
JVM GC垃圾回收初步了解
java·开发语言·jvm
~小先生~2 小时前
Python从入门到放弃(一)
开发语言·python
许彰午3 小时前
17_synchronized关键字深度解析
java·开发语言
z落落3 小时前
C# 泛型接口和泛型类+泛型约束
开发语言·c#
阿正的梦工坊3 小时前
【Rust】02-变量、不可变性与基础类型
开发语言·后端·rust
阿正的梦工坊3 小时前
【Rust】08-集合类型、字符串与迭代器入门
开发语言·rust·c#
FuckPatience3 小时前
C# 使用泛型协变将派生类类型替换为基类类型
开发语言·c#
张忠琳3 小时前
【Go 1.26.4】(Part 1) Go 1.26.4 超深度源码分析 — 总体架构与模块全景
开发语言·golang