iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 27
0
Modern Web

菜鳥前端奮鬥史(欸?系列 第 27

Day27 「使用 setInterval 排程囉」 ─ 嗯?好像不太對勁啊..?

暫且說到上一回,我們把 api 給 Call 爆了
那麼... 到底是怎麼把它給玩壞(#)的呢?

這一切的緣由都要從 setInterval 說起了..


最初的架構

我們有兩顆按鈕,分別是「去程路線」及「回程路線」

goBtn.addEventListener('click', getGoJson, false);
backBtn.addEventListener('click', getBackJson, false);

function getGoJson(){
    var xhr = new XMLHttpRequest();
    xhr.open('get', GoUrl);
    xhr.send(null);
    xhr.onload = function () {
        goData = JSON.parse(xhr.responseText);
        // ..中間省略
        }
    setInterval(getGoJson, 30000);
}
function getBackJson(){
    var xhr = new XMLHttpRequest();
    xhr.open('get', BackUrl);
    xhr.send(null);
    xhr.onload = function () {
        goData = JSON.parse(xhr.responseText);
        // ..中間省略
        }
    setInterval(getBackJson, 30000);
}

有看出端倪了嗎?

嗯...沒錯,我把 setInterval 寫到了 click 事件裡面 /images/emoticon/emoticon04.gif

click 之後觸發排程更新呀,有什麼問題嗎?

 
有,而且還滿嚴重的..
因為 setInterval 如果沒有被移除,就會一直存在
 
還是不清楚?

這麼做最恐怖的地方就是
「當使用者點擊一次按鈕時,我們會設定一次 setInterval 排程;若使用者點擊兩次,我們會設定一次相同的排程」

=> 也就是說,當使用者點了十下按鈕,背景其實同時有十個 setInterval 同時在運行
  30秒一到就發出10次 Request /images/emoticon/emoticon17.gif

而且一開始為了要檢查資料到底有沒有正確載入,我還很喪心病狂的使用3秒更新一次..
理所當然地,不出30分鐘 api 就立刻被 Call 爆啦

另外這麼做還有一個大問題
由於預設是去程路線的 setInterval 沒有被消除
即使點了回程路線按鈕的當下會把回程的到站時間資料渲染出來
但時間(30秒)一到,原先設定渲染去程路線的 setInterval 就會運作,再把畫面刷成 去程路線
 
 

更改過後呢?

我們改用一個全域變數去紀錄,目前到底要顯示 去程 還是 回程
然後 setInterval 裡面只呼叫一個 checkWay function

結果如下

var check = 'go'; // 預設顯示去程

function checkWay() {
    if (check == "go"){
        getGoJson();
    }
    else{
        getBackJson();
    }   
}
checkWay(); //先執行一次讓資料渲染到畫面上

goBtn.addEventListener('click', getGoJson, false);
backBtn.addEventListener('click', getBackJson, false);

function getGoJson(){
    clearInterval(getBackJson); // 讓畫面不會渲染出 回程路線
    check = "go";
    var xhr = new XMLHttpRequest();
    xhr.open('get', GoUrl);
    xhr.send(null);
    xhr.onload = function () {
        goData = JSON.parse(xhr.responseText);
        // ..中間省略
        }
}
function getBackJson(){
    clearInterval(getGoJson); // 讓畫面不會渲染出 去程路線
    check = "back";
    var xhr = new XMLHttpRequest();
    xhr.open('get', BackUrl);
    xhr.send(null);
    xhr.onload = function () {
        goData = JSON.parse(xhr.responseText);
        // ..中間省略
        }
}

setInterval(checkWay, 30000);

這樣子就不會有重複設定 setInterval ,同時也能正確渲染出「去、回程路線的公車到站時間」啦 /images/emoticon/emoticon37.gif


>>隊友任意門<<

我是小菜鳥阿陰,我們下次見!


上一篇
Day26 「親愛的,我把 api Call 爆了」 ─ status of 429 (Too Many Requests)
下一篇
Day28 「使用網頁等公車」 ─ 就來做搜尋功能囉!
系列文
菜鳥前端奮鬥史(欸?30

1 則留言

0
JasonYang
iT邦新手 5 級 ‧ 2018-01-16 00:48:05

加油加油~剩下3天!

阿陰 iT邦新手 5 級‧ 2018-01-16 22:54:06 檢舉

/images/emoticon/emoticon08.gif

我要留言

立即登入留言