摘要:代碼大體上是自頂向下的,但中間穿插著有關渲染,事件回應等異步代碼,他們將組成一個隊列,零秒延遲將會實現插隊操作。
js是單線程語言,但它允許通過設置超時值和間歇時間值來調度代碼在特定的時刻執行。setTimeout是在指定delay時間后,將指定方法作為異步任務添加到異步任務隊列中,而setInterval則是可以循環地每隔一個delay就向異步任務隊列中添加一個任務
語法 setTimeout// 返回唯一的ID let timeoutID = window.setTimeout(func[, delay, param1, param2, ...]); let timeoutID = window.setTimeout(code[, delay]);setInterval
// 返回唯一的ID let intervalID = window.setInterval(func, delay[, param1, param2, ...]); let intervalID = window.setInterval(code, delay);clearTimeout和clearInterval
window.clearTimeout(timeoutID) window.clearInterval(intervalID)
timeoutID/intervalID 可以用來作為clearTimeout/clearInterval方法的參數
func是在delay毫秒之后執行的函數
code 在第二種語法,是指你想要在delay毫秒之后執行的代碼字符串 (使用該語法是不推薦的, 不推薦的原因和eval()一樣)
delay 是延遲的毫秒數 (一秒等于1000毫秒),函數的調用會在該延遲之后發生。如果省略該參數,delay取默認值0。實際的延遲時間可能會比 delay 值長,原因看下面的介紹。此外,根據w3c文檔得知,當delay小于0的時候,delay按0來計算
setTimeout 和setInterval的使用方法類似,重點以setTimeout為例,有差異的地方再多帶帶分析。
例子1、比較一下下面兩個函數的區別
setTimeout(function () { func1() }, 0) setTimeout(function () { func1() })
0秒延遲,此回調將會放到一個能立即執行的時段進行觸發。javascript代碼大體上是自頂向下的,但中間穿插著有關DOM渲染,事件回應等異步代碼,他們將組成一個隊列,零秒延遲將會實現插隊操作。不寫第二個參數,瀏覽器自動配置時間,在IE,FireFox中,第一次配可能給個很大的數字,100ms上下,往后會縮小到最小時間間隔,Safari,chrome,opera則多為10ms上下。
---出自《javascript框架設計》
如果對0s的例子不明白,不要緊,我們繼續看下面這個:
var arr = [1,2,3]; for(var i in arr){ setTimeout(function(){console.log(arr[i])},0); console.log(arr[i]); }
控制臺會打印什么?
1 2 3 3 //3次
雖然setTimeout函數在每次循環的開始就調用了,但是卻被放到循環結束才執行,循環結束,i=3,接著連續打印了3次3。
這里涉及到了js單線程執行的問題:js在瀏覽器中是單線程執行的,必須在完成當前任務后才執行隊列中的下一個任務。此外對于js還維護著一個setTimeout隊列,未執行的setTimeout任務就按先后順序排在隊列中,等到主線程的普通任務隊列執行完后,主線程就按順序執行積累在setTimeout中的任務。所以上面的問題會先打印1、2、3.最后才打印3個3。
此時就有個疑問了,設置delay為0,而實際是大于0才執行的,何必呢?
實際上這里我們主要用來改變任務的執行順序,因為瀏覽器會在執行完當前任務隊列中的任務,再執行setTimeout隊列中積累的任務。通過設置任務在延遲到0s后執行,就能改變任務執行的先后順序,延遲該任務發生,使之異步執行。
2、delay后可以傳遞第三個及多個參數。
for (var i = 1; i < 4; i++) { var t = setTimeout(function(i) { console.log(i); // 2. 1 4.2 console.log(t); // 3. 3 5.3 clearTimeout(t); }, 10, i); } console.log(i);
控制臺會打印什么?
4 1 3 2 3
此處在每次循環中,都將i作為回調函數的參數i傳入,第一次傳入1,第二次傳入2,第三次傳入3。第四次不滿足循環條件,跳出循環,然后執行console.log(i)。主線程執行完當前任務隊里的任務,然后開始執行seTimeout的隊列。此時t為setTimeout最后的返回ID值3,則一次打印1,3 2,3。因為clearTimeout清楚了id為3的延時任務,所以只執行了兩次。故一次打印41323
僅IE不支持第三個及以上參數
3、關于this指向的問題
myArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) { alert(arguments.length > 0 ? this[sProperty] : this); }; myArray.myMethod(); // prints "zero,one,two" myArray.myMethod(1); // prints "one" setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1,5 seconds
由setTimeout()調用的代碼運行在與所在函數完全分離的執行環境上. 這會導致,這些代碼中包含的 this 關鍵字會指向 window (或全局)對象,這和所期望的this的值是不一樣的
如何解決this指向不確定的問題,我們可以用Function.prototype.bind()方法。
myArray = ["zero", "one", "two"]; myBoundMethod = (function (sProperty) { console.log(arguments.length > 0 ? this[sProperty] : this); }).bind(myArray); myBoundMethod(); // prints "zero,one,two" because "this" is bound to myArray in the function myBoundMethod(1); // prints "one" setTimeout(myBoundMethod, 1000); // still prints "zero,one,two" after 1 second because of the binding setTimeout(myBoundMethod, 1500, "1"); // prints "one" after 1.5 seconds應用
1、替換setInterval來實現重復定時
2、防止事件瘋狂觸發
3、IE下重新播放單次gif動畫
4、blur事件延時生效
[https://html.spec.whatwg.org/...
[http://imweb.io/topic/56ac67f...
[https://developer.mozilla.org...
[http://www.cnblogs.com/suspid...
[https://johnresig.com/blog/ho...
[http://www.cnblogs.com/snandy...
[http://www.ruanyifeng.com/blo...
[http://www.cnblogs.com/silin6...
文章地址:[http://17biu.cn/2017/07/18/se...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84113.html
摘要:后續的一些輔助性優化讀者可以自己琢磨,如函數指向,返回值保存等。 原文:https://keelii.github.io/2016/06/11/javascript-throttle/ 在瀏覽器 DOM 事件里面,有一些事件會隨著用戶的操作不間斷觸發。比如:重新調整瀏覽器窗口大?。╮esize),瀏覽器頁面滾動(scroll),鼠標移動(mousemove)。也就是說用戶在觸發這些瀏覽...
摘要:方法描述周期性地調用一個函數或者執行一段代碼。方法可取消由方法設置的。語法詳解是該延時操作的數字此隨后可以用來作為方法的參數。需要注意的是,不支持第一種語法中向延遲函數傳遞額外參數的功能。該值標識要取消的延遲執行代碼塊。 方法 描述 setInterval 周期性地調用一個函數(function)或者執行一段代碼。 clearInterval 取消掉用setI...
摘要:在元素被插入之前生效,在元素被插入之后的下一幀移除。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡動畫完成之后移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。版及以上定義進入過渡的結束狀態。 基本概念 Vue 在插入、更新或者移除 DOM 時,提供多種不同方式的應用過渡效果 在 CSS 過渡和動畫中自動應用 class 可以配合使用第三方 CSS 動畫庫,如...
摘要:在元素被插入之前生效,在元素被插入之后的下一幀移除。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡動畫完成之后移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。版及以上定義進入過渡的結束狀態。 基本概念 Vue 在插入、更新或者移除 DOM 時,提供多種不同方式的應用過渡效果 在 CSS 過渡和動畫中自動應用 class 可以配合使用第三方 CSS 動畫庫,如...
閱讀 3142·2021-10-08 10:04
閱讀 1080·2021-09-30 09:48
閱讀 3449·2021-09-22 10:53
閱讀 1664·2021-09-10 11:22
閱讀 1682·2021-09-06 15:00
閱讀 2142·2019-08-30 15:56
閱讀 704·2019-08-30 15:53
閱讀 2273·2019-08-30 13:04