setInterval(),setTimeout() 會返回一個值,通常認爲是ID,將這個ID值傳遞給clearInterval(),clearTimeout() 能夠取消執行,例如:javascript
1
2
3
4
5
6
7
8
|
var
intervalTimer = setInterval(
function
() {
console.log(1)
},
3000);
console.log(intervalTimer);
//通常是一個數字,Number
button.onclick =
function
() {
clearInterval(intervalTimer);
};
|
setInterval(),setTimeout() 方法是瀏覽器 window 對象提供,因此第一個參數函數中的this指向window對象,這跟變量的做用域有關:html
1
2
3
4
5
6
7
8
9
10
11
|
var
a = 1;
var
obj = {
a: 2,
b:
function
() {
setTimeout(
function
() {
console.log(
this
.a);
//這裏返回的是:1;
},
2000);
}
};
obj.b();
|
固然你能夠經過使用bind()方法來改變這個狀況:html5
1
2
3
4
5
6
7
8
9
10
|
var
a = 1;
var
obj = {
a: 2,
b:
function
() {
setTimeout(
function
() {
console.log(
this
.a);
//這裏返回的是:2;
}.bind(
this
), 2000);
//注意這行
}
};
obj.b();
|
關於bind()方法,你能夠看這裏:http://helloweb.wang/qianduankaifa/Js%20JQuery/2015-12-06/403.htmljava
你們都知道setInterval()和setTimeout()能夠接收兩個參數,第一個參數是須要回調的函數,必須傳入的參數,第二個參數是時間間隔,毫秒數,能夠省略,這個能夠看文章的下面,不傳第二個參數,瀏覽器自動配置時間,在IE,FireFox中,第一次配可能給個很大的數字,100ms上下,日後會縮小到最小時間間隔,Safari,chrome,opera則多爲10ms上下。web
可是我要說的固然不是這個,我要說的是setInterval()和setTimeout()能夠接收更多的參數,那麼這些參數是幹什麼用的呢?從第三個參數開始,依次用來表示第一個參數(回調函數)傳入的參數,例如:chrome
1
2
3
|
setTimeout(
function
(a,b){
console.log(1+a+b);
//這裏打印的是:8
},1000,3,4);
|
固然一些古老的瀏覽器是不支持的。後端
clearInterval()和clearTimeout()實際上是通用的,就是說你能夠用 clearInterval() 取消 setTimeout() 執行,clearTimeout()一樣能夠取消 setInterval() 執行。瀏覽器
1
2
3
4
5
6
7
8
|
var
intervalTimer = setInterval(
function
() {
console.log(1)
},
3000);
console.log(intervalTimer);
button.onclick =
function
() {
clearTimeout(intervalTimer);
//注意這裏,不是clearInterval哦
};
|
定義很簡單多線程
setTimeout() 方法用於在指定的毫秒數後調用函數或計算表達式。框架
普遍應用場景:定時器,輪播圖,動畫效果,自動滾動等等
上面一些應該是setTimeout在你們心中的樣子,由於咱們日常使用也不是不少。
可是setTimeout真的有那麼簡單嗎?
一個題目,若是你在一段代碼中發現下面內容
1
2
3
4
|
var
startTime =
new
Date();
setTimeout(
function
() {
console.log(
new
Date() - startTime);
}, 100)
|
請問最後打印的是多少?
我以爲正確答案是,取決於後面同步執行的js須要佔用多少時間。
MAX(同步執行的時間, 100)。
再加一個題目,只有下面代碼
1
2
3
4
|
setTimeout(
function
() {
func1();
}, 0)
func2();
|
func1和func2誰會先執行?
這個答案應該比較簡單,func2先執行,func1後面執行。
再來一題
1
2
3
|
setTimeout(
function
() {
func1()
}, 0)
|
和
1
2
3
|
setTimeout(
function
() {
func1()
})
|
有什麼差異?
0秒延遲,此回調將會放到一個能當即執行的時段進行觸發。javascript代碼大致上是自頂向下的,但中間穿插着有關DOM渲染,事件迴應等異步代碼,他們將組成一個隊列,零秒延遲將會實現插隊操做。
不寫第二個參數,瀏覽器自動配置時間,在IE,FireFox中,第一次配可能給個很大的數字,100ms上下,日後會縮小到最小時間間隔,Safari,chrome,opera則多爲10ms上下。
上面答案來自《javascript框架設計》
好了,看了上面幾個題目是否是感受setTimeout不是想象中那樣了。
下面是我本身的一些理解:
首先須要注意javascript是單線程的,特色就是容易出現阻塞。若是一段程序處理時間很長,很容易致使整個頁面hold住。什麼交互都處理不了怎麼辦?
簡化複雜度?複雜邏輯後端處理?html5的多線程?
上面都是ok的作法,可是setTimeout也是處理這種問題的一把好手。
setTimeout一個很關鍵的用法就是分片,若是一段程序過大,咱們能夠拆分紅若干細小的塊。
例如上面的狀況,咱們將那一段複雜的邏輯拆分處理,分片塞入隊列。這樣即便在複雜程序沒有處理完時,咱們操做頁面,也是能獲得即便響應的。其實就是將交互插入到了複雜程序中執行。
換一種思路,上面就是利用setTimeout實現一種僞多線程的概念。
有個函數庫Concurrent.Thread.js 就是實現js的多線程的。
一個簡單使用的例子,引入Concurrent.Thread.js後
1
2
3
4
5
6
7
8
|
Concurrent.Thread.create(
function
() {
for
(
var
i = 0; i < 1000000; i++) {
console.log(i);
};
});
$(
'#test'
).click(
function
() {
alert(1);
});
|
雖然有個巨大的循環,可是這時不妨礙你去觸發alert();
是否是很厲害~
還有一種場景,當咱們須要渲染一個很複雜的DOM時,例如table組件,複雜的構圖等等,假如整個過程須要3s,咱們是等待徹底處理完成在呈現,仍是使用一個setTimeout分片,將內容一片一片的斷續呈現。
其實setTimeout給了咱們不少優化交互的空間。