1. 程式人生 > >setTimeout與setInterval的坑以及優缺點

setTimeout與setInterval的坑以及優缺點

說到setTimeout與setInrerval大家可能都覺得很easy,我剛接觸js的也是這樣的想法,可後來在知乎看到了一道題,大概好像是這樣的:

例一:

setTimeout(function(){

console.log("小馬“);

setTimeout(function(){arguments.callee;},1000);

},1000)

例二:

setInterval(function(){console.log("小馬“);},1000);

問一與二的區別?

說實話我剛看到這個題目的時候是懵比的,因為我覺得這兩者是完全一樣的呀,都是間隔1000ms之後執行回撥的呀,可是既然這麼問了肯定他們之間是有區別的,於是乎我就去查了相關的資料,果然,二者不僅僅是有差別的,而且定時器也顛覆了我以往的認知。

首先,這兩個定時器的基本含義我就不重複了,我覺得只要是個學前端的肯定沒有不知道的。為什麼說定時器也顛覆了我以往的認知呢?因為我發現定時器的回撥函式並不是相當於在時間到了就執行,而是有一個主js執行程序,這個程序是頁面剛載入的時候頁面按照載入順序執行的js程式碼,此外還有一個需要在程序空閒的時候執行的程式碼佇列,而我們所說的定時器的回撥就是相當於(以上的例一為例)在1000ms之後把定時器回撥放入到空閒佇列中(注意,空閒佇列有可能還有其它的程式碼,比如點選事件,因此定時器回撥放入的位置不一定是空閒佇列的開始位置!)舉個例子:

 var i=0;

function a(){

t=setTimeout(function(){console.log("小明")},0);

}

a();

alert(”小紅“);

 此時你會發現先彈出小紅,又彈出的小明!!

好了,簡單的可以理解位定時器和js其他程式是並行執行的,不過jquery的作者有一篇文章專門介紹這個佇列的,有興趣的可以搜一下看看!!

接下來說第二點,就是例一與例二的區別:

setInterval有個很煩的地方就是當js主程式空閒時候,執行程式碼佇列裡面的程式碼的時候,如果此時候我們有一個問題,定時器是等到回撥執行完,才開始計時進行下次迴圈呢?還是隻要一次計時完畢,插入回撥之後不管回撥執不執行就開始計時呢?答案顯然是後者,這也就是我說setInterval坑比的原因啊,因為這會出現一種情況,當我們插入回撥的時候前佇列有別的程式碼在執行,這時候回撥肯定是不會執行的,因此如果這個時候無限定時時間到了會再次插入回撥,這個時候如果發現佇列中的第一次回撥沒有執行,那麼再次插入的回撥瀏覽器就預設取消,(這是以防出現回撥連續執行多次的情況)但是這又引發了新的情況就是有些回撥是不能取消掉的?

這就是我們經常使用例一代替例二的原因,例一可以避免上述的情況。累,很簡單的東西被我說的這麼複雜,我也是醉了,看來文字功底還很欠缺,可是我的夢想是新時代的作家,這可咋整呢?