在開發功能「軌跡播放」時,遇到了一個狀況。
原先同事已經開發了一版,此次有個新功能:點擊線上任意一點後能夠從點擊處從新播放。
看了一下原來的版本,發現同時使用了setTimeout和setInterval,二者配合實現點線播放。
簡單結構以下html
function test() { setInterval(function () { console.log("interval"); //省略插值方法獲得arr (...) play(arr); }, 2000); } function play(arr) { setTimeout(function () { play(arr); console.log("setTimeout"); }, 40); }
我以爲這個結構欠妥,兩個定時器配合一定會出現失誤!所以重構了一版,將兩個定時器改成一個,用setInterval解決。
可是此時我並不知道欠妥欠在什麼地方,缺少理論支持,如今閒下來仔細研究了一下ajax
在仔細研究了舊版本後,我先把舊版本結構扒了出來,排除其餘因素,本身模擬了一個簡單版(就是上面的代碼)
setTimeout:在執行時,是在載入後延遲指定時間後,去執行一次表達式,僅執行一次
setInterval:在執行時,它從載入後,每隔指定的時間就執行一次表達式瀏覽器
從結果得出兩點結論網絡
function test() { setInterval(function () { console.log("interval"); play(); }, 2000); } function play() { //延遲執行 for (var i = 0; i < 100000000; i++) { } setTimeout(function () { play(); console.log("setTimeout"); }, 40); }
從結果得出兩點結論多線程
從結果得出結論函數
綜上實驗結果,網上搜集了一些資料能說明問題:線程
在作軌跡播放時,setInterval的延遲還在可接受範圍以內,可是網上給出的最佳解決方案是用setTimeout作。
setTimeout只會執行一次,在執行完成後,從新啓動新的Timeout,時間runtime計算設置爲差時,減小出現間隔愈來愈大的狀況code
function test() { //runTime,計算差時 runTime = 1000 - 執行耗時; setTimeout(callback, runTime); } setTimeout(test, 1000);