JavaScript实现可终止轮询请求的方法_第1页
JavaScript实现可终止轮询请求的方法_第2页
JavaScript实现可终止轮询请求的方法_第3页
JavaScript实现可终止轮询请求的方法_第4页
JavaScript实现可终止轮询请求的方法_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第JavaScript实现可终止轮询请求的方法目录什么是轮询请求?轮询的要点setInterval的问题实现轮询准备工作基础版进阶版最终版最近遇到了一个需求,需要每隔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,返回一个start和stop方法用于开始和停止轮询

!DOCTYPEhtml

htmllang="en"

head

metacharset="UTF-8"/

metahttp-equiv="X-UA-Compatible"content="IE=edge"/

metaname="viewport"content="width=device-width,initial-scale=1.0"/

titleDocument/title

/head

body

buttonid="start"开始/button

buttonid="stop"停止/button

/body

/html

script

conststartBtn=document.getElementById('start')

conststopBtn=document.getElementById('stop')

//轮询在这

functionmyInterval(){

return{

start:()={},

stop:()={}

//轮询管理器

constintervalManager=myInterval(main)

//轮询的方法

letcount=0

functionmain(){

count+=1

console.log('执行:',count)

startBtn.addEventListener('click',intervalManager.start)

stopBtn.addEventListener('click',intervalManager.stop)

/script

基础版

functionmyInterval(callback,interval=2000){

lettimerId

constloop=async()={

callback()

return(timer=setTimeout(loop,interval))

return{

start:()={

loop()

stop:()={

console.log('停止执行')

clearTimeout(timerId)

}

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

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

functionmain(){

count+=1

console.log('执行:',count)

if(count==5){

count=0

intervalManager.stop()

}

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

看一下loop方法

constloop=async()={

callback()

return(timerId=setTimeout(()={

loop()

},interval))

}

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

进阶版

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

//可以自动停止的定时器

functionmyInterval(callback,interval=2000){

lettimer

letisStop=false

conststop=()={

console.log('停止')

isStop=true

clearTimeout(timer)

conststart=()={

isStop=false

loop()

constloop=async()={

callback()

if(isStop)return

return(timer=setTimeout(loop,interval))

return{

start,

stop

}

下面把main方法再改一改

functionmain(){

constflag=parseInt(Math.random()*2)===1

console.log('flag',flag)

returnflagPromise.resolve():Promise.reject()

}

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

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

最终版

用async和await可以实现main方法中出现错误的时候中止轮询

functionmyInterval(callback,interval=2000){

lettimer

letisStop=false

conststop=()={

console.log('停止')

isStop=true

clearTimeout(timer)

conststart=async()={

isStop=false

awaitloop()

constloop=async()={

try{

awaitcallback(stop)

}catch(err){

console.error('轮询出错:',err)

thrownewError('轮询出错:',err)

if(isStop)return

return(timer=setTimeout(loop,interval))

return{

start,

stop

}

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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论