下午四點,天氣晴朗,陽光明媚,等着下班
產品:我但願頁面上的這個數據實時變化
開發:···,能夠,用那個叫着WebSocket的東西,再找一個封裝好框架,如:mqtt(感受本身好機智)
產品:要開發很久
開發:嗯,三天,五天,仍是···
產品:我但願今天上線
開發:···,···,···(不能描述的語言,話說segmentfault爲何不支持表情)
開發:果斷選擇輪詢javascript
<!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>
開發:今晚的月亮真圓啊,下班了···html
產品:我但願這個實時加載,能爲所欲爲,我喊它加載就加載,喊它停就停
研發:(石化中···)java
<!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>
開發:(這麼可貴需求我都實現了,我是否是已是專家了,我是否是應該升職加薪,接着贏娶白富美,走向人生巔峯,哈哈哈)
正沉醉於本身的成果中
產品:你的有bug
開發:(絕對不信中,確定是你握鼠標的姿式不對,手感很差),怎麼可能有bug,你是否是環境有問題,還在用ie6,多刷新幾回
產品:···,你按鈕多點幾回,點快點,試試,數據會屢次請求
開發:半信半疑的去嘗試,還真是(好奇怪,檢查了一圈沒有發現任何問題)segmentfault
看似沒有任何問題,找不到問題的時候就只有一點點試錯,最終發現去掉const { data } = await getData()以後,問題消失,請求的時間越長,出現的機率越高
畫個圖分析一下
先看一下js執行過程,按鈕的click事件也至關於異步,而後咱們再來文字分析一下,問題出現的緣由瀏覽器
bug產生的時機
框架
這就是爲何,請求的時間越長,出現的機率越高異步
<!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>