js polling and stepped pit

background

Four in the afternoon the weather was clear and sunny, waiting for commuting
Products: I hope this real-time data changes on the page
development: ..., you can use the WebSocket shouted something, find a good package framework, such as: mqtt (feel good wit)
product: to develop for a long time
to develop: ah, three, five, or ???
products: I hope today on-line
development: · · ·, ..., ... (language can describe, Why do not you support the words of segmentfault expression)
development: decisive choice poll

In development

<!DOCTYPE HTML>
<html>
<head>
  <title>轮询的坑</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
</body>
<script type="text/javascript">
  function getData() {
      return new Promise((resolve,reject) => {
          setTimeout(() => {
              resolve({data:666})
          },500)
      })
  }
  // 轮询
  async function start () {
    const { data } = await getData() // 模拟请求
    console.log(data)
    timerId = setTimeout(start, 1000)
  }
  start ()
</script>
</html>

Development: Tonight the moon really round ah, got off work ???

the next day

Product: I hope this real-time load, able to do anything, I shout it to load on to load, call it government stop
research and development in the petrochemical :( ???)

Continue to develop in

<!DOCTYPE HTML>
<html>
<head>
  <title>轮询的坑</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
    <button id="button">暂停</button>
</body>
<script type="text/javascript">
  let timerId = null
  function getData() {
      return new Promise((resolve,reject) => {
          setTimeout(() => {
              resolve({data:666})
          },500)
      })
  }
  // 轮询
  async function start () {
    const { data } = await getData() // 模拟请求
    console.log(data)
    timerId = setTimeout(start, 1000)
  }
  // 暂停
  function stop () {
    clearTimeout(timerId)
  }

  start ()

  const botton = document.querySelector("#button")
  let isPlay = true
  botton.addEventListener("click", function(){
    isPlay = !isPlay
    botton.innerHTML = isPlay ? '暂停' : '播放'
    isPlay ? start() : stop()
  }, false)
</script>
</html>

:( such a rare development needs I have realized that I was not already an expert, and I was not really deserve a raise, then win marry white Fu-mei, to the pinnacle of life, ha ha ha)
being immersed in their results in
the product: you have a bug
to develop :( absolutely do not believe in, certainly you hold the mouse position does not feel bad), how could a bug, you are not environmental problems, still use ie6, refresh a few times
product: · · you button several times more, the point quickly, try, repeatedly requested data will be
developed: dubious to try, it really is (surprise, checked around and found no problems)

Analysis process

  1. Into a page execution start (), is a start async function, such as asynchronous synchronization which will perform the same, the end timerId function = setTimeout (start, 1000), 1000 milliseconds after the start (), forming a wheel Inquiry (the interval between each request there is certainly greater than 1000 + 500, as to why, you can go look at the implementation of the principles browser asynchronous)
  2. After the setTimeout id assigned to timerId, click the button to clear the current timer

Seemingly no problem, when the problem can not be found only a little bit of trial and error, eventually found after removing the const {data} = await getData ( ), the problem goes away, the longer the time of the request, the higher the probability of
drawing a map analyze the reasons js look at the implementation process, click the button event is also equivalent to asynchronous and then let us analyze the text, problems
image description

The reason bug occurs

  1. If there is no const {data} = await getData () this step, when clicked, click the callback function can be executed, indicating that the current js certainly is idle (always remember, js single-threaded), when the setTimeout (start , 1000) certainly an asynchronous state (js that only perform one task),
  2. clearTimeout (timerId) can easily clear this mission will not let it enter js execution threads execute
  3. After adding const {data} = await getData (), if now in setTimeout js callback function has been performed and waits await getData () in, js is idle, click may be performed, click cleared execution of the callback function setTimeout ( the reason timerId = setTimeout (start, 1000), and thus can not stop the cycle, which is generated by the bug; callback function has been performed), there is no clear await getData () callback function, the code will continue to implement console.log (data)

Timing bug generated
image description

That is why, the longer the time of the request, the higher the probability of

solution

<!DOCTYPE HTML>
<html>
<head>
  <title>轮询的坑</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
    <button id="button">暂停</button>
</body>
<script type="text/javascript">
  let timerId = 1 // 模拟计时器id,唯一性
  let timerObj = {} // 计时器存储器
  function getData() {
      return new Promise((resolve,reject) => {
          setTimeout(() => {
              resolve({data:666})
          },500)
      })
  }
  // 轮询
  function start () {
    const id = timerId++
    timerObj[id] = true
    async function timerFn () {
      if (!timerObj[id]) return
      const { data } = await getData() // 模拟请求
      console.log(data)
      setTimeout(timerFn, 1000)
    }
    timerFn()
  }
  // 暂停
  function stop () {
    timerObj = {}
  }

  start ()

  const botton = document.querySelector("#button")
  let isPlay = true
  botton.addEventListener("click", function(){
    isPlay = !isPlay
    botton.innerHTML = isPlay ? '暂停' : '播放'
    isPlay ? start() : stop()
  }, false)
</script>
</html>

Guess you like

Origin www.cnblogs.com/baimeishaoxia/p/11939286.html