iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript实现可终止轮询请求的方法
  • 456
分享到

JavaScript实现可终止轮询请求的方法

2024-04-02 19:04:59 456人浏览 八月长安
摘要

目录什么是轮询请求?轮询的要点setInterval的问题实现轮询准备工作基础版进阶版最终版最近遇到了一个需求,需要每隔5s请求一个接口获取接口返回的结果,返回成功后停止请求,接口的

最近遇到了一个需求,需要每隔5s请求一个接口获取接口返回的结果,返回成功后停止请求,接口的返回的值有下面几种情况:

// 成功
{
    "code": 0,
    "msg": '成功'
}
// 查询中
{
    "code": -1,
    "msg": '结果查询中'
}
// 失败
{
    "code": 1,
    "msg": '返回结果失败'
}

code是接口的状态码,为0的时候表示接口返回的成功,这时就不需要再请求接口。

实现这种需求首先想到的就是用轮询去做了。

什么是轮询请求?

通俗地说,轮询请求就是间隔相同的时间(如5s)后不断地向服务端发起同一个接口的请求,当然不能无限次去请求,所以轮询必须要有个停止轮询的机制

轮询的要点

1. 按照需要选择是否立即发起请求再进入轮询

2. 上一次的请求响应后到了指定的时间间隔后再继续执行下一次请求

3. 当轮询的请求发生报错的时候应该停止轮询

4. 被停止的轮询可以根据需要再次发起轮询

setInterval的问题

因为是不断请求,所以首先能想到的就是用setInterval去实现,但是setInterval做轮询的话,会有以下严重的问题

1. 即使调用的代码报错了,setInterval会持续的调用

2. setInterval不会等到上一次的请求响应后再执行,只要到了指定的时间间隔就会执行,哪怕有报错也会执行

3. setInterval定时不准确,这个跟事件循环有关,这里不展开啦~

实现轮询

实现轮询,只要按照轮询的要点去实现一个setInterval方法就可以了,下面用setTimeout一步步去实现这个方法

准备工作

首先准备一个html模板,这个模板包含两个按钮,一个开启轮询,一个停止轮询,轮询的方法命名为myInterval,返回一个startstop方法用于开始和停止轮询

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta Http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="start">开始</button>
    <button id="stop">停止</button>
  </body>
</html>
<script>
  const startBtn = document.getElementById('start')
  const stopBtn = document.getElementById('stop')
  
  // 轮询在这
  function myInterval() {
      return {
          start: () => {},
          stop: () => {}
      }
  }
  
  // 轮询管理器
  const intervalManager = myInterval(main)
  
  // 轮询的方法
  let count = 0
  function main() {
    count += 1
    console.log('执行:', count)
  }
  
  startBtn.addEventListener('click', intervalManager.start)
  stopBtn.addEventListener('click', intervalManager.stop)
</script>

基础版

function myInterval(callback, interval = 2000) {
    let timerId
    const loop = async () => {
      callback()
      return (timer = setTimeout(loop, interval))
    }
    return {
      start: () => {
        loop()
      },
      stop: () => {
        console.log('停止执行')
        clearTimeout(timerId)
      }
    }
  }

这个版本基本跟setInterval的功能一致了,只不过执行需要手动调用start,停止要调用stop。

一个常见的场景是,当轮询执行n次后,停止轮询,下面改一下main方法,等count等于5的时候停止轮询

function main() {
    count += 1
    console.log('执行:', count)
    if (count == 5) {
      count = 0
      intervalManager.stop()
    }
}

发现当count等于5时,确实调用了stop方法,但是却没有停止轮询,当点击停止按钮的时候,又停止了轮询,这是什么情况呢?

看一下loop方法

const loop = async () => {
  callback()
  return (timerId = setTimeout(() => {
    loop()
  }, interval))
}

因为是在callback中执行stop的,stop并没有阻止定时器中回调(loop)的执行,所以看起来是停止了,但是新的定时器还是开启了

进阶版

解决基础版无法自动停止的问题也很简单,加一个变量来检测,一旦执行了stop方法不返回定时器就可以了

// 可以自动停止的定时器
function myInterval(callback, interval = 2000) {
    let timer
    let isStop = false
    const stop = () => {
      console.log('停止')
      isStop = true
      clearTimeout(timer)
    }
    const start = () => {
      isStop = false
      loop()
    }
    const loop = async () => {
      callback()
      if (isStop) return
      return (timer = setTimeout(loop, interval))
    }
    return {
      start,
      stop
    }
  }

下面把main方法再改一改

function main() {
    const flag = parseInt(Math.random() * 2) === 1
    console.log('flag', flag)
    return flag ? Promise.resolve() : Promise.reject()
}

main方法这次返回的是Promise,我们来看看执行的情况

进阶版还是不支持main中有Promise的情况,我们希望的是,当main中出现Promise reject和错误的时候,中止轮询

最终版

asyncawait可以实现main方法中出现错误的时候中止轮询

function myInterval(callback, interval = 2000) {
    let timer
    let isStop = false
    const stop = () => {
      console.log('停止')
      isStop = true
      clearTimeout(timer)
    }
    const start = async () => {
      isStop = false
      await loop()
    }
    const loop = async () => {
      try {
        await callback(stop)
      } catch (err) {
        console.error('轮询出错:', err)
        throw new Error('轮询出错:', err)
      }
      if (isStop) return
      return (timer = setTimeout(loop, interval))
    }
    return {
      start,
      stop
    }
  }

可以看到最终版能满足我们的轮询要求了,遇到接口报错的时候可以终止请求,细心的您应该能发现这行代码 callback(stop),是的,main中现在多了一个回调方法,可以直接调用该方法停止轮询

main再次改回来

let count = 0
function main(stop) {
    count += 1
    console.log('count:', count)
    if (count == 5) {
      stop()
    }
}

可以看到,调用stop也是可以中止轮询的

现在一个完美的js可终止轮询请求,interval就完成啦~

到此这篇关于用javascript实现可终止的轮询请求的文章就介绍到这了,更多相关js轮询请求内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript实现可终止轮询请求的方法

本文链接: https://www.lsjlt.com/news/151377.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript实现可终止轮询请求的方法
    目录什么是轮询请求?轮询的要点setInterval的问题实现轮询准备工作基础版进阶版最终版最近遇到了一个需求,需要每隔5s请求一个接口获取接口返回的结果,返回成功后停止请求,接口的...
    99+
    2022-11-13
  • vue轮询请求解决方案的完整实例
    轮询的理解 其实轮询的重点在于间隔多少时间执行一次,而并非循环本身。ajax是异步请求,从发起请求到接受到响应即为一个完整的过程,这个过程所需要的时间是无法预料的,说的极端点,若请...
    99+
    2022-11-12
  • iOS Moya实现OAuth请求的方法
    0. 起源 开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 而...
    99+
    2022-06-05
    iOS Moya OAuth 请求
  • golang中实现graphql请求的方法
    目录前言安装gqlgen初始化项目编写schema生成代码编写resolver运行GraphQL服务安装Apollo客户端创建Apollo客户端执行GraphQL请求结论前言 Gra...
    99+
    2023-05-16
    golang库gqlgen使用 golang graphql请求
  • JavaScript实现请求服务端接口方法详解
    JavaScript 中请求服务端接口的代码实现可能会因为使用的方法而有所不同。 1、使用 XMLHttpRequest: var xhr = new XMLHttpRequest(...
    99+
    2023-01-31
    JS请求服务端接口 JavaScript请求服务端接口
  • Go 实现 Nginx 加权轮询算法的方法步骤
    目录一,Nginx 负载均衡的轮询 (round-robin)1. nginx 中的配置2. 简单介绍3. 特点4. 实现 (这里使用golang模拟实现)5. 测试二,Ngi...
    99+
    2022-06-07
    GO 方法 算法 Nginx
  • 实现HTTP请求的方法有哪些
    本篇文章为大家展示了实现HTTP请求的方法有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、HTTP的请求与响应HTTP协议(HyperText Transfer Protocol,超文本传输...
    99+
    2023-05-31
    http请求 请求
  • Vue实现可复用轮播组件的方法
    本文用vue简单的实现了一个轮播图的基础功能,并抽离出来作为一个公共组件,方便复用 html和js部分 <template>   <div     class="i...
    99+
    2022-09-27
  • Go实现Nginx加权轮询算法的方法是什么
    本篇文章给大家分享的是有关Go实现Nginx加权轮询算法的方法是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一,Nginx 负载均衡的轮询 (round-robin)在说...
    99+
    2023-06-21
  • C语言中pthread_exit()函数实现终止线程的方法
    本篇文章和大家了解一下C语言中pthread_exit()函数实现终止线程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。多线程编程中,线程结束执行的方式有 3 种,分别是:线程将指定函数体中的代码执行完后自行结束;...
    99+
    2023-07-06
  • springboot接受前端请求的方法实现
    目录普通参数get 请求post请求5种不同参数类型的传递普通参数[简单数据]:参数不同名实体类参数属性名里面引用别的属性名数组参数集合类型错误案例报错:解决方法总结首先我们是否用的...
    99+
    2023-01-28
    springboot接受前端请求 springboot 前端请求
  • PHP实现网络请求的方法总结
    一、分析php发送网网络请求的方法 对于php发送网络请求,我们最常用的请求就是curl,有时我们也会用到file_get_contents函数发送网络请求,但file_get_co...
    99+
    2022-11-13
  • 使用JavaScript实现轮播图的方法有哪些
    使用JavaScript实现轮播图的方法有哪些?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。思想:在大的容器里,装着一个很长的表,表是容器宽度的整数倍。然后通过更改列表样式里的...
    99+
    2023-06-14
  • AngularJS中$http模块POST请求的实现方法
    小编给大家分享一下AngularJS中$http模块POST请求的实现方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、代码...
    99+
    2022-10-19
  • Jdk11使用HttpClient提交Http2请求的实现方法
    HTTP2协议的强制要求https,如果⽬标URI是HTTP的,则⽆法使⽤HTTP 2协议 测试 -> https://http2.akamai.com/demo ...
    99+
    2022-11-13
  • SpringBoot配置Controller实现Web请求处理的方法
    今天小编给大家分享的是SpringBoot配置Controller实现Web请求处理的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。Controller处理请求由于 在建立 Sp...
    99+
    2023-08-03
  • android实现http中请求访问添加cookie的方法
    本文实例讲述了android实现http中请求访问添加cookie的方法。分享给大家供大家参考,具体如下: 第一种 HashMap<String, String>...
    99+
    2022-06-06
    HTTP 方法 cookie Android
  • 在PHP中怎么实现GET和POST请求的方法
    本篇内容主要讲解“在PHP中怎么实现GET和POST请求的方法 ”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在PHP中怎么实现GET和POST请求的方法 ”吧...
    99+
    2022-10-19
  • vue中如何实现基于axios的ajax请求方法
    小编给大家分享一下vue中如何实现基于axios的ajax请求方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如下所示:imp...
    99+
    2022-10-19
  • spring retry实现方法请求重试的使用步骤
    目录1 spring-retry是什么?2 使用步骤2.1 引入maven库2.2 在spring启动类上开启重试功能2.3 公共业务代码2.4 传统的重试做法2.5 使用sprin...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作