当前位置:首页 > JavaScript

js实现轮询

2026-04-06 02:07:12JavaScript

轮询的基本概念

轮询(Polling)是一种客户端定期向服务器发送请求以检查数据更新的技术。适用于需要实时性但无法使用WebSocket或Server-Sent Events(SSE)的场景。

使用 setInterval 实现基础轮询

通过 setInterval 定时发起请求,简单但可能造成资源浪费:

js实现轮询

function startPolling(url, interval = 5000) {
  const poll = setInterval(async () => {
    try {
      const response = await fetch(url);
      const data = await response.json();
      console.log('Polled data:', data);
    } catch (error) {
      console.error('Polling error:', error);
    }
  }, interval);

  // 返回清除函数以便手动停止
  return () => clearInterval(poll);
}

// 使用示例
const stopPolling = startPolling('https://api.example.com/data');
// 停止轮询:stopPolling();

使用 setTimeout 实现递归轮询

更灵活的方案,可根据服务器响应动态调整间隔:

js实现轮询

function recursivePolling(url, interval = 5000) {
  setTimeout(async () => {
    try {
      const response = await fetch(url);
      const data = await response.json();
      console.log('Polled data:', data);

      // 根据响应决定下次轮询时间(如服务器返回建议间隔)
      const nextInterval = data.nextPollInterval || interval;
      recursivePolling(url, nextInterval);
    } catch (error) {
      console.error('Polling error:', error);
      // 错误时重试,可增加退避策略
      recursivePolling(url, interval * 2);
    }
  }, interval);
}

// 启动
recursivePolling('https://api.example.com/data');

带退避策略的轮询

避免频繁失败请求导致资源浪费,常见策略如指数退避:

function pollingWithBackoff(url, initialInterval = 1000, maxInterval = 60000) {
  let currentInterval = initialInterval;

  const poll = async () => {
    try {
      const response = await fetch(url);
      const data = await response.json();
      console.log('Polled data:', data);

      // 成功时重置间隔
      currentInterval = initialInterval;
    } catch (error) {
      console.error('Polling error:', error);
      // 失败时增加间隔,不超过最大值
      currentInterval = Math.min(currentInterval * 2, maxInterval);
    } finally {
      setTimeout(poll, currentInterval);
    }
  };

  poll();
}

// 启动
pollingWithBackoff('https://api.example.com/data');

终止轮询的条件控制

通过标志位或AbortController实现可控终止:

function controllablePolling(url, interval = 5000) {
  let isPolling = true;
  const abortController = new AbortController();

  const poll = async () => {
    if (!isPolling) return;

    try {
      const response = await fetch(url, { 
        signal: abortController.signal 
      });
      const data = await response.json();
      console.log('Polled data:', data);
    } catch (error) {
      if (error.name !== 'AbortError') {
        console.error('Polling error:', error);
      }
    } finally {
      if (isPolling) {
        setTimeout(poll, interval);
      }
    }
  };

  poll();

  // 提供终止方法
  return {
    stop: () => {
      isPolling = false;
      abortController.abort();
    }
  };
}

// 使用示例
const { stop } = controllablePolling('https://api.example.com/data');
// 停止轮询:stop();

注意事项

  • 性能影响:频繁轮询会增加服务器负载,需合理设置间隔。
  • 竞态条件:确保请求顺序与响应顺序一致,必要时使用请求ID标记。
  • 错误处理:网络波动时需实现重试或退避逻辑。
  • 替代方案:优先考虑WebSocket或SSE等长连接技术(若支持)。

标签: js
分享给朋友:

相关文章

js实现验证码

js实现验证码

实现验证码的JavaScript方法 生成随机验证码 使用Math.random()生成随机字符串,结合数字和字母: function generateCaptcha() { const cha…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现计算器

js实现计算器

实现基础计算器功能 使用JavaScript创建一个基础计算器需要处理数字输入、运算符逻辑和结果显示。以下是一个简单的实现示例: let currentInput = '0'; let previo…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('image…

js分组实现

js分组实现

分组实现方法 在JavaScript中,可以通过多种方式实现数组或对象的分组操作。以下是几种常见的方法: 使用Array.prototype.reduce() 通过reduce方法可以轻松实现数组分…