經常看到setTimeout延時0ms的javascript代碼,感到很迷惑,難道延時0ms和不延時不是一個道理嗎?后來通過查資料以及實驗得出以下兩個作用,可能還有作用我還不知道,希望得知的朋友在后面評論上不吝指出。
1、實現javascript的異步;
正常情況下javascript都是按照順序執行的。但是我們可能讓該語句后面的語句執行完再執行本身,這時就可以用到setTimeout延時0ms來實現了。
如:
alert(1);
setTimeout("alert(2)", 0);
alert(3);
雖然延時了0ms,但是執行順序為:1,3,2
這樣就保證setTimeout里面的語句在某一代碼段中最后執行。
2、在事件中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執行,以及完成文檔當前狀態更新后,告訴瀏覽器去啟用 setTimeout 內注冊的函數。;
舉個例子來說這句話的意思,假如當某個事件在頁面上建立一個文本框,並給文本框賦值(完成文檔當前狀態更新),然后將焦點定到文本框,並且選中文本框的內容(后面部分就需要用到setTimeout 延遲0ms實現,否則不好實現)。
看個例子:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta charset="utf-8"> <title>setTimeout</title> <script type="text/javascript" > (function(){ function get(id){ return document.getElementById(id); } window.onload = function(){ get('makeinput').onmousedown = function(){ var input = document.createElement('input'); input.setAttribute('type', 'text'); input.setAttribute('value', 'test1'); get('inpwrapper').appendChild(input); input.focus(); input.select(); } get('makeinput2').onmousedown = function(){ var input = document.createElement('input'); input.setAttribute('type', 'text'); input.setAttribute('value', 'test1'); get('inpwrapper2').appendChild(input); setTimeout(function(){ input.focus(); input.select(); }, 0); } get('input1').onkeypress = function(){ get('preview1').innerHTML = this.value; } get('input2').onkeypress = function(){ setTimeout(function(){ get('preview2').innerHTML = get('input2').value; },0 ); } } })(); </script> </head> <body> <h1><code>DEMO1</code></h1> <h2>1、未使用 <code>setTimeout</code>(未選中文本框內容)</h2> <button id="makeinput">生成 input</button> <p id="inpwrapper"></p> <h2>2、使用 <code>setTimeout</code>(立即選中文本框內容)</h2> <button id="makeinput2">生成 input</button></h2> <p id="inpwrapper2"></p> -------------------------------------------------------------------------- <h1><code>DEMO2</code></h1> <h2>1、未使用 <code>setTimeout</code>(只有輸入第二個字符時,前一個字符才顯示出來)</h2> <input type="text" id="input1" value=""/><div id="preview1"></div> <h2>2、使用 <code>setTimeout</code>(輸入時,字符同時顯示出來)</h2> <input type="text" id="input2" value=""/><div id="preview2"></div> </body> </html>
現有的 JavaScript 引擎是單線程處理任務的。它把任務放到隊列中,不會同步去執行,必須在完成一個任務后才開始另外一個任務。
在DEMO1中,JavaScript 引擎在執行 onmousedown時,會先執行alert(123),然后執行select和focus調用,由於此時還沒有創建好DOM元素,不會得到期望的結果,然后執行創建操作。相反 如果我們改變調用的執行順序即可,“先執行“ 元素的創建,使用settimeout延遲0毫秒再執行select和focus調用。核心在於,把select和focus調用加入到任務隊列,待調用棧清空后再“立即執行任務“