Vue 中实现轮询请求的三种主流方案:vue-request、@vueuse/core 与 RxJS 实战解析

简介:在 Vue 项目中使用 vue-request、@vueuse/core 和 rxjs 实现轮询请求的方法,并结合实时监控、订单状态更新等场景提供完整代码示例,适合中高级前端开发者学习和应用

在现代前端开发中,轮询(Polling)是一种常见的异步数据获取方式,尤其适用于需要实时更新数据的场景,如:

  • 实时监控仪表盘
  • 聊天消息同步
  • 订单状态更新
  • 后台任务执行进度

本文将围绕 Vue 框架,介绍如何使用 vue-request、@vueuse/core 和 rxjs 三种主流方案实现轮询请求,并结合实际应用场景进行讲解。

一、什么是轮询?

轮询是指客户端以固定时间间隔向服务器发送请求,主动获取最新数据。虽然不是最高效的通信方式(相比 WebSocket),但在某些简单场景下依然非常实用,尤其是在服务端不支持长连接的情况下。

二、技术选型对比

方案 特点 适用场景
vue-request 简洁易用,基于函数式调用,内置轮询、防抖、节流等特性 快速实现轮询功能
@vueuse/core 基于 Composition API,与 Vue 3 深度集成,提供 useIntervalFn 等工具函数 更加灵活控制轮询逻辑
rxjs 强大的响应式编程库,支持复杂的数据流处理 需要精细控制数据流和错误处理

三、方案详解与示例

1. 使用 vue-request 实现轮询请求

vue-request 是一个类 React 的 ahooks 风格的 Vue 数据请求 Hook 库,非常适合 Vue 3 + Composition API 项目。

安装:

npm install vue-request

示例代码

import { defineComponent } from 'vue'
import useRequest from 'vue-request'
import axios from 'axios'

export default defineComponent({
  setup() {
    const fetchData = async () => {
      const res = await axios.get('/api/realtime-data')
      return res.data
    }

    const { data, loading } = useRequest(fetchData, {
      pollingWhenHidden: false, // 页面隐藏时不轮询
      pollingInterval: 5000,     // 每5秒请求一次
    })

    return () => (
      <div>
        {loading.value ? '加载中...' : JSON.stringify(data.value)}
      </div>
    )
  }
})

优势:

  • 内置轮询、缓存、错误重试等功能
  • 支持自动取消请求
  • 可与 Vue 组件生命周期良好配合

2. 使用 @vueuse/core 实现轮询

@vueuse/core 提供了大量 Vue 3 的组合式函数,其中 useIntervalFn 是实现轮询的理想选择。

安装:

npm install @vueuse/core

示例代码

import { defineComponent, ref } from 'vue'
import { useIntervalFn } from '@vueuse/core'
import axios from 'axios'

export default defineComponent({
  setup() {
    const data = ref(null)
    const loading = ref(false)

    const fetchData = async () => {
      loading.value = true
      try {
        const res = await axios.get('/api/realtime-data')
        data.value = res.data
      } catch (error) {
        console.error('请求失败:', error)
      } finally {
        loading.value = false
      }
    }

    const { pause, resume, isActive } = useIntervalFn(fetchData, 5000, {
      immediate: true,
      callback: fetchData
    })

    return () => (
      <div>
        <button onClick={isActive.value ? pause : resume}>
          {isActive.value ? '暂停轮询' : '开始轮询'}
        </button>
        {loading.value ? '加载中...' : JSON.stringify(data.value)}
      </div>
    )
  }
})

优势:

  • 精细控制轮询启动/暂停
  • 支持组件卸载时自动清理定时器
  • 可与其他组合函数结合使用(如 useFetch)

3. 使用 rxjs 实现轮询

RxJS 是一个强大的响应式编程库,适合需要构建复杂异步数据流的场景。

安装:

npm install rxjs

示例代码

import { defineComponent, onMounted, onUnmounted, ref } from 'vue'
import { interval, Subscription, from } from 'rxjs'
import { switchMap } from 'rxjs/operators'
import axios from 'axios'

export default defineComponent({
  setup() {
    const data = ref(null)
    const loading = ref(false)
    const error = ref(null)
    let subscription: Subscription

    onMounted(() => {
      subscription = interval(5000).pipe(
        switchMap(() => {
          loading.value = true
          return from(axios.get('/api/realtime-data'))
        })
      ).subscribe({
        next: (res) => {
          data.value = res.data
          loading.value = false
        },
        error: (err) => {
          error.value = err.message
          loading.value = false
        }
      })
    })

    onUnmounted(() => {
      if (subscription) subscription.unsubscribe()
    })

    return () => (
      <div>
        {loading.value && <p>加载中...</p>}
        {error.value && <p style="color: red;">{error.value}</p>}
        {data.value && <pre>{JSON.stringify(data.value, null, 2)}</pre>}
      </div>
    )
  }
})

优势:

  • 构建复杂的数据流(如合并多个请求、节流、过滤)
  • 错误处理更强大
  • 支持取消订阅,避免内存泄漏

四、轮询的应用场景分析

场景 描述 推荐方案
实时订单状态更新 用户查看订单状态是否已支付或完成 @vueuse/core 或 vue-request
后台任务进度监控 如文件上传、视频转码等长时间任务 rxjs(便于链式处理)
聊天应用中的新消息检测 当前页面未使用 WebSocket 时 vue-request(简洁高效)
数据大屏展示 多个图表定期刷新数据 @vueuse/core(可统一控制)

五、轮询的注意事项

1. 性能优化:

控制轮询频率,避免频繁请求影响性能。页面不可见时暂停轮询(如使用 visibilitychange 事件)

2. 防止内存泄漏

在组件销毁时清除定时器或取消订阅

3. 错误处理机制

请求失败时进行重试或提示用户

4. 服务器压力

尽量减少并发请求数量,合理设置间隔时间

总结:

根据你的项目需求和技术栈,可以选择最适合的轮询方案。对于大多数中小型项目,推荐使用 vue-request @vueuse/core;如果你有复杂的异步流程需求,rxjs 是更好的选择。

 

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1