# 宿¶å¨ JavaScript æä¾å®æ¶æ§è¡ä»£ç çåè½ï¼å«å宿¶å¨ï¼timerï¼ï¼ä¸»è¦ç±`setTimeout()`å`setInterval()`è¿ä¸¤ä¸ªå½æ°æ¥å®æãå®ä»¬åä»»å¡éåæ·»å 宿¶ä»»å¡ã ## setTimeout() `setTimeout`彿°ç¨æ¥æå®æä¸ªå½æ°æææ®µä»£ç ï¼å¨å¤å°æ¯«ç§ä¹åæ§è¡ãå®è¿åä¸ä¸ªæ´æ°ï¼è¡¨ç¤ºå®æ¶å¨çç¼å·ï¼ä»¥åå¯ä»¥ç¨æ¥åæ¶è¿ä¸ªå®æ¶å¨ã ```javascript var timerId = setTimeout(func|code, delay); ``` ä¸é¢ä»£ç ä¸ï¼`setTimeout`彿°æ¥åä¸¤ä¸ªåæ°ï¼ç¬¬ä¸ä¸ªåæ°`func|code`æ¯å°è¦æ¨è¿æ§è¡ç彿°åæè 䏿®µä»£ç ï¼ç¬¬äºä¸ªåæ°`delay`æ¯æ¨è¿æ§è¡çæ¯«ç§æ°ã ```javascript console.log(1); setTimeout('console.log(2)',1000); console.log(3); // 1 // 3 // 2 ``` ä¸é¢ä»£ç ä¼å è¾åº1å3ï¼ç¶åçå¾ 1000毫ç§åè¾åº2ãæ³¨æï¼`console.log(2)`å¿ é¡»ä»¥å符串çå½¢å¼ï¼ä½ä¸º`setTimeout`çåæ°ã 妿æ¨è¿æ§è¡çæ¯å½æ°ï¼å°±ç´æ¥å°å½æ°åï¼ä½ä¸º`setTimeout`çåæ°ã ```javascript function f() { console.log(2); } setTimeout(f, 1000); ``` `setTimeout`ç第äºä¸ªåæ°å¦æçç¥ï¼åé»è®¤ä¸º0ã ```javascript setTimeout(f) // çåäº setTimeout(f, 0) ``` é¤äºåä¸¤ä¸ªåæ°ï¼`setTimeout`è¿å 许æ´å¤çåæ°ãå®ä»¬å°ä¾æ¬¡ä¼ å ¥æ¨è¿æ§è¡ç彿°ï¼åè°å½æ°ï¼ã ```javascript setTimeout(function (a,b) { console.log(a + b); }, 1000, 1, 1); ``` ä¸é¢ä»£ç ä¸ï¼`setTimeout`å ±æ4ä¸ªåæ°ãæåé£ä¸¤ä¸ªåæ°ï¼å°å¨1000毫ç§ä¹ååè°å½æ°æ§è¡æ¶ï¼ä½ä¸ºåè°å½æ°çåæ°ã è¿æä¸ä¸ªéè¦æ³¨æçå°æ¹ï¼å¦æåè°å½æ°æ¯å¯¹è±¡çæ¹æ³ï¼é£ä¹`setTimeout`ä½¿å¾æ¹æ³å é¨ç`this`å ³é®åæåå ¨å±ç¯å¢ï¼è䏿¯å®ä¹æ¶æå¨çé£ä¸ªå¯¹è±¡ã ```javascript var x = 1; var obj = { x: 2, y: function () { console.log(this.x); } }; setTimeout(obj.y, 1000) // 1 ``` ä¸é¢ä»£ç è¾åºçæ¯1ï¼è䏿¯2ãå 为å½`obj.y`å¨1000毫ç§åè¿è¡æ¶ï¼`this`ææåçå·²ç»ä¸æ¯`obj`äºï¼èæ¯å ¨å±ç¯å¢ã 为äºé²æ¢åºç°è¿ä¸ªé®é¢ï¼ä¸ç§è§£å³æ¹æ³æ¯å°`obj.y`æ¾å ¥ä¸ä¸ªå½æ°ã ```javascript var x = 1; var obj = { x: 2, y: function () { console.log(this.x); } }; setTimeout(function () { obj.y(); }, 1000); // 2 ``` ä¸é¢ä»£ç ä¸ï¼`obj.y`æ¾å¨ä¸ä¸ªå¿å彿°ä¹ä¸ï¼è¿ä½¿å¾`obj.y`å¨`obj`çä½ç¨åæ§è¡ï¼è䏿¯å¨å ¨å±ä½ç¨åå æ§è¡ï¼æä»¥è½å¤æ¾ç¤ºæ£ç¡®çå¼ã å¦ä¸ç§è§£å³æ¹æ³æ¯ï¼ä½¿ç¨`bind`æ¹æ³ï¼å°`obj.y`è¿ä¸ªæ¹æ³ç»å®å¨`obj`ä¸é¢ã ```javascript var x = 1; var obj = { x: 2, y: function () { console.log(this.x); } }; setTimeout(obj.y.bind(obj), 1000) // 2 ``` ## setInterval() `setInterval`彿°çç¨æ³ä¸`setTimeout`å®å ¨ä¸è´ï¼åºå«ä» ä» å¨äº`setInterval`æå®æä¸ªä»»å¡æ¯é䏿®µæ¶é´å°±æ§è¡ä¸æ¬¡ï¼ä¹å°±æ¯æ 鿬¡ç宿¶æ§è¡ã ```javascript var i = 1 var timer = setInterval(function() { console.log(2); }, 1000) ``` ä¸é¢ä»£ç ä¸ï¼æ¯é1000毫ç§å°±è¾åºä¸ä¸ª2ï¼ä¼æ éè¿è¡ä¸å»ï¼ç´å°å ³éå½åçªå£ã ä¸`setTimeout`䏿 ·ï¼é¤äºåä¸¤ä¸ªåæ°ï¼`setInterval`æ¹æ³è¿å¯ä»¥æ¥åæ´å¤çåæ°ï¼å®ä»¬ä¼ä¼ å ¥åè°å½æ°ã ä¸é¢æ¯ä¸ä¸ªéè¿`setInterval`æ¹æ³å®ç°ç½é¡µå¨ç»çä¾åã ```javascript var div = document.getElementById('someDiv'); var opacity = 1; var fader = setInterval(function() {   opacity -= 0.1;   if (opacity >= 0) {     div.style.opacity = opacity;   } else {     clearInterval(fader);   } }, 100); ``` ä¸é¢ä»£ç æ¯é100毫ç§ï¼è®¾ç½®ä¸æ¬¡`div`å ç´ çéæåº¦ï¼ç´è³å ¶å®å ¨éæä¸ºæ¢ã `setInterval`çä¸ä¸ªå¸¸è§ç¨éæ¯å®ç°è½®è¯¢ãä¸é¢æ¯ä¸ä¸ªè½®è¯¢ URL ç Hash 弿¯å¦åçååçä¾åã ```javascript var hash = window.location.hash; var hashWatcher = setInterval(function() {   if (window.location.hash != hash) {     updatePage();   } }, 1000); ``` `setInterval`æå®çæ¯âå¼å§æ§è¡âä¹é´çé´éï¼å¹¶ä¸èèæ¯æ¬¡ä»»å¡æ§è¡æ¬èº«ææ¶èçæ¶é´ãå æ¤å®é ä¸ï¼ä¸¤æ¬¡æ§è¡ä¹é´çé´éä¼å°äºæå®çæ¶é´ãæ¯å¦ï¼`setInterval`æå®æ¯ 100ms æ§è¡ä¸æ¬¡ï¼æ¯æ¬¡æ§è¡éè¦ 5msï¼é£ä¹ç¬¬ä¸æ¬¡æ§è¡ç»æå95毫ç§ï¼ç¬¬äºæ¬¡æ§è¡å°±ä¼å¼å§ãå¦æææ¬¡æ§è¡èæ¶ç¹å«é¿ï¼æ¯å¦éè¦105毫ç§ï¼é£ä¹å®ç»æåï¼ä¸ä¸æ¬¡æ§è¡å°±ä¼ç«å³å¼å§ã 为äºç¡®ä¿ä¸¤æ¬¡æ§è¡ä¹é´æåºå®çé´éï¼å¯ä»¥ä¸ç¨`setInterval`ï¼èæ¯æ¯æ¬¡æ§è¡ç»æåï¼ä½¿ç¨`setTimeout`æå®ä¸ä¸æ¬¡æ§è¡çå ·ä½æ¶é´ã ```javascript var i = 1; var timer = setTimeout(function f() { // ... timer = setTimeout(f, 2000); }, 2000); ``` ä¸é¢ä»£ç å¯ä»¥ç¡®ä¿ï¼ä¸ä¸æ¬¡æ§è¡æ»æ¯å¨æ¬æ¬¡æ§è¡ç»æä¹åç2000毫ç§å¼å§ã ## clearTimeout()ï¼clearInterval() `setTimeout`å`setInterval`彿°ï¼é½è¿åä¸ä¸ªæ´æ°å¼ï¼è¡¨ç¤ºè®¡æ°å¨ç¼å·ãå°è¯¥æ´æ°ä¼ å ¥`clearTimeout`å`clearInterval`彿°ï¼å°±å¯ä»¥åæ¶å¯¹åºç宿¶å¨ã ```javascript var id1 = setTimeout(f, 1000); var id2 = setInterval(f, 1000); clearTimeout(id1); clearInterval(id2); ``` ä¸é¢ä»£ç ä¸ï¼åè°å½æ°`f`ä¸ä¼åæ§è¡äºï¼å ä¸ºä¸¤ä¸ªå®æ¶å¨é½è¢«åæ¶äºã `setTimeout`å`setInterval`è¿åçæ´æ°å¼æ¯è¿ç»çï¼ä¹å°±æ¯è¯´ï¼ç¬¬äºä¸ª`setTimeout`æ¹æ³è¿åçæ´æ°å¼ï¼å°æ¯ç¬¬ä¸ä¸ªçæ´æ°å¼å¤§1ã ```javascript function f() {} setTimeout(f, 1000) // 10 setTimeout(f, 1000) // 11 setTimeout(f, 1000) // 12 ``` ä¸é¢ä»£ç ä¸ï¼è¿ç»è°ç¨ä¸æ¬¡`setTimeout`ï¼è¿åå¼é½æ¯ä¸ä¸æ¬¡å¤§äº1ã å©ç¨è¿ä¸ç¹ï¼å¯ä»¥åä¸ä¸ªå½æ°ï¼åæ¶å½åææç`setTimeout`宿¶å¨ã ```javascript (function() { // æ¯è½®äºä»¶å¾ªç¯æ£æ¥ä¸æ¬¡ var gid = setInterval(clearAllTimeouts, 0); function clearAllTimeouts() { var id = setTimeout(function() {}, 0); while (id > 0) { if (id !== gid) { clearTimeout(id); } id--; } } })(); ``` ä¸é¢ä»£ç ä¸ï¼å è°ç¨`setTimeout`ï¼å¾å°ä¸ä¸ªè®¡ç®å¨ç¼å·ï¼ç¶åæç¼å·æ¯å®å°ç计æ°å¨å ¨é¨åæ¶ã ## å®ä¾ï¼debounce 彿° ææ¶ï¼æä»¬ä¸å¸æåè°å½æ°è¢«é¢ç¹è°ç¨ãæ¯å¦ï¼ç¨æ·å¡«å ¥ç½é¡µè¾å ¥æ¡çå 容ï¼å¸æéè¿ Ajax æ¹æ³ä¼ åæå¡å¨ï¼jQuery çåæ³å¦ä¸ã ```javascript $('textarea').on('keydown', ajaxAction); ``` è¿æ ·åæä¸ä¸ªå¾å¤§ç缺ç¹ï¼å°±æ¯å¦æç¨æ·è¿ç»å»é®ï¼å°±ä¼è¿ç»è§¦å`keydown`äºä»¶ï¼é æå¤§éç Ajax éä¿¡ãè¿æ¯ä¸å¿ è¦çï¼èä¸å¾å¯è½äº§çæ§è½é®é¢ãæ£ç¡®çåæ³åºè¯¥æ¯ï¼è®¾ç½®ä¸ä¸ªé¨æ§å¼ï¼è¡¨ç¤ºä¸¤æ¬¡ Ajax éä¿¡çæå°é´éæ¶é´ã妿å¨é´éæ¶é´å ï¼åçæ°ç`keydown`äºä»¶ï¼åä¸è§¦å Ajax éä¿¡ï¼å¹¶ä¸éæ°å¼å§è®¡æ¶ã妿è¿äºæå®æ¶é´ï¼æ²¡æåçæ°ç`keydown`äºä»¶ï¼åå°æ°æ®åéåºå»ã è¿ç§åæ³å«å debounceï¼é²æå¨ï¼ãåå®ä¸¤æ¬¡ Ajax éä¿¡çé´éä¸å¾å°äº2500毫ç§ï¼ä¸é¢ç代ç å¯ä»¥æ¹åæä¸é¢è¿æ ·ã ```javascript $('textarea').on('keydown', debounce(ajaxAction, 2500)); function debounce(fn, delay){ var timer = null; // 声æè®¡æ¶å¨ return function() { var context = this; var args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; } ``` ä¸é¢ä»£ç ä¸ï¼åªè¦å¨2500毫ç§ä¹å ï¼ç¨æ·å次å»é®ï¼å°±ä¼åæ¶ä¸ä¸æ¬¡ç宿¶å¨ï¼ç¶ååæ°å»ºä¸ä¸ªå®æ¶å¨ãè¿æ ·å°±ä¿è¯äºåè°å½æ°ä¹é´çè°ç¨é´éï¼è³å°æ¯2500毫ç§ã ## è¿è¡æºå¶ `setTimeout`å`setInterval`çè¿è¡æºå¶ï¼æ¯å°æå®ç代ç ç§»åºæ¬è½®äºä»¶å¾ªç¯ï¼çå°ä¸ä¸è½®äºä»¶å¾ªç¯ï¼åæ£æ¥æ¯å¦å°äºæå®æ¶é´ã妿å°äºï¼å°±æ§è¡å¯¹åºç代ç ï¼å¦æä¸å°ï¼å°±ç»§ç»çå¾ ã è¿æå³çï¼`setTimeout`å`setInterval`æå®çåè°å½æ°ï¼å¿ é¡»çå°æ¬è½®äºä»¶å¾ªç¯çææåæ¥ä»»å¡é½æ§è¡å®ï¼æä¼å¼å§æ§è¡ãç±äºåé¢çä»»å¡å°åºéè¦å¤å°æ¶é´æ§è¡å®ï¼æ¯ä¸ç¡®å®çï¼æä»¥æ²¡æåæ³ä¿è¯ï¼`setTimeout`å`setInterval`æå®çä»»å¡ï¼ä¸å®ä¼æç §é¢å®æ¶é´æ§è¡ã ```javascript setTimeout(someTask, 100); veryLongTask(); ``` ä¸é¢ä»£ç ç`setTimeout`ï¼æå®100毫ç§ä»¥åè¿è¡ä¸ä¸ªä»»å¡ã使¯ï¼å¦æåé¢ç`veryLongTask`彿°ï¼åæ¥ä»»å¡ï¼è¿è¡æ¶é´é常é¿ï¼è¿äº100毫ç§è¿æ æ³ç»æï¼é£ä¹è¢«æ¨è¿è¿è¡ç`someTask`å°±åªæççï¼çå°`veryLongTask`è¿è¡ç»æï¼æè½®å°å®æ§è¡ã åçä¸ä¸ª`setInterval`çä¾åã ```javascript setInterval(function () { console.log(2); }, 1000); sleep(3000); function sleep(ms) { var start = Date.now(); while ((Date.now() - start) < ms) { } } ``` ä¸é¢ä»£ç ä¸ï¼`setInterval`è¦æ±æ¯é1000毫ç§ï¼å°±è¾åºä¸ä¸ª2ã使¯ï¼ç´§æ¥çç`sleep`è¯å¥éè¦3000æ¯«ç§æè½å®æï¼é£ä¹`setInterval`å°±å¿ é¡»æ¨è¿å°3000毫ç§ä¹åæå¼å§çæã注æï¼çæå`setInterval`ä¸ä¼äº§ç累积æåºï¼å³ä¸ä¼ä¸ä¸åè¾åºä¸ä¸ª2ï¼èæ¯åªä¼è¾åºä¸ä¸ª2ã ## setTimeout(f, 0) ### å«ä¹ `setTimeout`çä½ç¨æ¯å°ä»£ç æ¨è¿å°æå®æ¶é´æ§è¡ï¼å¦ææå®æ¶é´ä¸º`0`ï¼å³`setTimeout(f, 0)`ï¼é£ä¹ä¼ç«å»æ§è¡åï¼ çæ¡æ¯ä¸ä¼ãå 为ä¸ä¸è说è¿ï¼å¿ é¡»è¦çå°å½åèæ¬ç忥任å¡ï¼å ¨é¨å¤çå®ä»¥åï¼æä¼æ§è¡`setTimeout`æå®çåè°å½æ°`f`ãä¹å°±æ¯è¯´ï¼`setTimeout(f, 0)`ä¼å¨ä¸ä¸è½®äºä»¶å¾ªç¯ä¸å¼å§å°±æ§è¡ã ```javascript setTimeout(function () { console.log(1); }, 0); console.log(2); // 2 // 1 ``` ä¸é¢ä»£ç å è¾åº`2`ï¼åè¾åº`1`ãå 为`2`æ¯åæ¥ä»»å¡ï¼å¨æ¬è½®äºä»¶å¾ªç¯æ§è¡ï¼è`1`æ¯ä¸ä¸è½®äºä»¶å¾ªç¯æ§è¡ã æ»ä¹ï¼`setTimeout(f, 0)`è¿ç§åæ³çç®çæ¯ï¼å°½å¯è½æ©å°æ§è¡`f`ï¼ä½æ¯å¹¶ä¸è½ä¿è¯ç«å»å°±æ§è¡`f`ã å®é ä¸ï¼`setTimeout(f, 0)`ä¸ä¼ççå¨0毫ç§ä¹åè¿è¡ï¼ä¸åçæµè§å¨æä¸åçå®ç°ã以 Edge æµè§å¨ä¸ºä¾ï¼ä¼çå°4毫ç§ä¹åè¿è¡ã妿çµèæ£å¨ä½¿ç¨çµæ± ä¾çµï¼ä¼çå°16毫ç§ä¹åè¿è¡ï¼å¦æç½é¡µä¸å¨å½å Tab 页ï¼ä¼æ¨è¿å°1000毫ç§ï¼1ç§ï¼ä¹åè¿è¡ãè¿æ ·æ¯ä¸ºäºèçç³»ç»èµæºã ### åºç¨ `setTimeout(f, 0)`æå 个é常éè¦çç¨éãå®çä¸å¤§åºç¨æ¯ï¼å¯ä»¥è°æ´äºä»¶çåç顺åºãæ¯å¦ï¼ç½é¡µå¼åä¸ï¼æä¸ªäºä»¶å åçå¨åå ç´ ï¼ç¶ååæ³¡å°ç¶å ç´ ï¼å³åå ç´ çäºä»¶åè°å½æ°ï¼ä¼æ©äºç¶å ç´ çäºä»¶åè°å½æ°è§¦åãå¦æï¼æ³è®©ç¶å ç´ çäºä»¶åè°å½æ°å åçï¼å°±è¦ç¨å°`setTimeout(f, 0)`ã ```javascript // HTML 代ç å¦ä¸ // var input = document.getElementById('myButton'); input.onclick = function A() { setTimeout(function B() { input.value +=' input'; }, 0) }; document.body.onclick = function C() { input.value += ' body' }; ``` ä¸é¢ä»£ç å¨ç¹å»æé®åï¼å 触ååè°å½æ°`A`ï¼ç¶å触å彿°`C`ã彿°`A`ä¸ï¼`setTimeout`å°å½æ°`B`æ¨è¿å°ä¸ä¸è½®äºä»¶å¾ªç¯æ§è¡ï¼è¿æ ·å°±èµ·å°äºï¼å 触åç¶å ç´ çåè°å½æ°`C`çç®çäºã å¦ä¸ä¸ªåºç¨æ¯ï¼ç¨æ·èªå®ä¹çåè°å½æ°ï¼é叏卿µè§å¨çé»è®¤å¨ä½ä¹å触åãæ¯å¦ï¼ç¨æ·å¨è¾å ¥æ¡è¾å ¥ææ¬ï¼`keypress`äºä»¶ä¼å¨æµè§å¨æ¥æ¶ææ¬ä¹å触åãå æ¤ï¼ä¸é¢çåè°å½æ°æ¯è¾¾ä¸å°ç®ççã ```javascript // HTML 代ç å¦ä¸ // document.getElementById('input-box').onkeypress = function (event) { this.value = this.value.toUpperCase(); } ``` ä¸é¢ä»£ç æ³å¨ç¨æ·æ¯æ¬¡è¾å ¥ææ¬åï¼ç«å³å°å符转为大åã使¯å®é ä¸ï¼å®åªè½å°æ¬æ¬¡è¾å ¥åçå符转为大åï¼å 为æµè§å¨æ¤æ¶è¿æ²¡æ¥æ¶å°æ°çææ¬ï¼æä»¥`this.value`åä¸å°ææ°è¾å ¥çé£ä¸ªå符ãåªæç¨`setTimeout`æ¹åï¼ä¸é¢çä»£ç æè½åæ¥ä½ç¨ã ```javascript document.getElementById('input-box').onkeypress = function() { var self = this; setTimeout(function() { self.value = self.value.toUpperCase(); }, 0); } ``` ä¸é¢ä»£ç å°ä»£ç æ¾å ¥`setTimeout`ä¹ä¸ï¼å°±è½ä½¿å¾å®å¨æµè§å¨æ¥æ¶å°ææ¬ä¹å触åã ç±äº`setTimeout(f, 0)`å®é 䏿å³çï¼å°ä»»å¡æ¾å°æµè§å¨ææ©å¯å¾çç©ºé²æ¶æ®µæ§è¡ï¼æä»¥é£äºè®¡ç®é大ãèæ¶é¿çä»»å¡ï¼å¸¸å¸¸ä¼è¢«æ¾å°å 个å°é¨åï¼å嫿¾å°`setTimeout(f, 0)`é颿§è¡ã ```javascript var div = document.getElementsByTagName('div')[0]; // åæ³ä¸ for (var i = 0xA00000; i < 0xFFFFFF; i++) { div.style.backgroundColor = '#' + i.toString(16); } // åæ³äº var timer; var i=0x100000; function func() { timer = setTimeout(func, 0); div.style.backgroundColor = '#' + i.toString(16); if (i++ == 0xFFFFFF) clearTimeout(timer); } timer = setTimeout(func, 0); ``` ä¸é¢ä»£ç æä¸¤ç§åæ³ï¼é½æ¯æ¹åä¸ä¸ªç½é¡µå ç´ çèæ¯è²ãåæ³ä¸ä¼é ææµè§å¨âå µå¡âï¼å 为 JavaScript æ§è¡é度è¿é«äº DOMï¼ä¼é æå¤§é DOM æä½âå 积âï¼èåæ³äºå°±ä¸ä¼ï¼è¿å°±æ¯`setTimeout(f, 0)`ç好å¤ã å¦ä¸ä¸ªä½¿ç¨è¿ç§æå·§çä¾åæ¯ä»£ç é«äº®çå¤çã妿代ç åå¾å¤§ï¼ä¸æ¬¡æ§å¤çï¼å¯è½ä¼å¯¹æ§è½é æå¾å¤§çååï¼é£ä¹å°å ¶åæä¸ä¸ªä¸ªå°åï¼ä¸æ¬¡å¤çä¸åï¼æ¯å¦åæ`setTimeout(highlightNext, 50)`çæ ·åï¼æ§è½ååå°±ä¼åè½»ã