您好,登錄后才能下訂單哦!
【寫在前面的胡言亂語】
自從大三開始實習之后,就沒有寫博客了,雖然學了很多東西,但是如果沒有進行總結和分享,學的東西就很容易忘記,而且不進行分享,就不會手動去敲代碼,這樣對知識的理解就不夠透徹。
現在畢業半年多了,最近學習了《JavaScript高級程序設計》這本書,受益匪淺,看了才知道雖然自己寫了那么多JS,但是對JS的理解最多就只是中下水平。
現在看第二遍,邊看邊敲代碼,邊分享,希望看到這篇文章的你,能有所收獲。
【這是正文】
《JavaScript高級程序設計》這本書里面,介紹了很多關于setTimeout函數的神奇使用,今天來介紹下第一個——使用setTimeout代替setInterval進行間歇調用。
書中是這么說的
“在開發環境下,很少使用間歇調用(setInterval),原因是后一個間歇調用很可能在前一個間歇調用結束前啟動”。
這話怎么理解呢?
首先我們來看一下一般情況下的setInterval函數的使用,以及如何使用setTimeout代替setInterval
var executeTimes = 0; var intervalTime = 500; var intervalId = null; // 放開下面的注釋運行setInterval的Demo intervalId = setInterval(intervalFun,intervalTime); // 放開下面的注釋運行setTimeout的Demo // setTimeout(timeOutFun,intervalTime); function intervalFun(){ executeTimes++; console.log("doIntervalFun——"+executeTimes); if(executeTimes==5){ clearInterval(intervalId); } } function timeOutFun(){ executeTimes++; console.log("doTimeOutFun——"+executeTimes); if(executeTimes<5){ setTimeout(arguments.callee,intervalTime); } }
代碼比較簡單,我們只是在setTimeout的方法里面又調用了一次setTimeout,就可以達到間歇調用的目的。
重點來了,為什么作者建議我們使用setTimeout代替setInterval呢?setTimeout式的間歇調用和傳統的setInterval間歇調用有什么區別呢?
區別在于,setInterval間歇調用,是在前一個方法執行前,就開始計時,比如間歇時間是500ms,那么不管那時候前一個方法是否已經執行完畢,都會把后一個方法放入執行的序列中。這時候就會發生一個問題,假如前一個方法的執行時間超過500ms,加入是1000ms,那么就意味著,前一個方法執行結束后,后一個方法馬上就會執行,因為此時間歇時間已經超過500ms了。
書中沒有給出代碼證明這個結論,于是自己寫了一段代碼來驗證。
var executeTimes = 0; var intervalTime = 500; var intervalId = null; var oriTime = new Date().getTime(); // 放開下面的注釋運行setInterval的Demo intervalId = setInterval(intervalFun,intervalTime); // 放開下面的注釋運行setTimeout的Demo // setTimeout(timeOutFun,intervalTime); function intervalFun(){ executeTimes++; var nowExecuteTimes = executeTimes; var timeDiff = new Date().getTime() - oriTime; console.log("doIntervalFun——"+nowExecuteTimes+", after " + timeDiff + "ms"); var delayParam = 0; sleep(1000); console.log("doIntervalFun——"+nowExecuteTimes+" finish !"); if(executeTimes==5){ clearInterval(intervalId); } } function timeOutFun(){ executeTimes++; var nowExecuteTimes = executeTimes; var timeDiff = new Date().getTime() - oriTime; console.log("doTimeOutFun——"+nowExecuteTimes+", after " + timeDiff + "ms"); var delayParam = 0; sleep(1000); console.log("doTimeOutFun——"+nowExecuteTimes+" finish !"); if(executeTimes<5){ setTimeout(arguments.callee,intervalTime); } } function sleep(sleepTime){ var start=new Date().getTime(); while(true){ if(new Date().getTime()-start>sleepTime){ break; } } }
(這里使用大牛提供的sleep函數來模擬函數運行的時間)
執行setInterval的Demo方法,看控制臺
可以發現,fun2和fun1開始的間歇接近1000ms,剛好就是fun1的執行時間,也就意味著fun1執行完后fun2馬上就執行了,和我們間歇調用的初衷背道而馳。
我們注釋掉setInterval的Demo方法,放開setTimeout的Demo方法,運行,查看控制臺
這下終于正常了,fun1和fun2相差了1500ms = 1000 + 500,fun2在fun1執行完的500ms后執行。
不知道你有沒有和我一樣腦洞大開,反正我是感覺視野又開闊了一點,setTimeout的妙用還有很多,下次接著聊!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。