settimeout(0) 的作用解析


家都知道 JavaScript 中的 setTimeout() 可用來延遲執行一段代碼,如:

setTimeout( function() {
alert("Hello World");
}, 1000) //延時1秒

 

今天在網上看到了 setTimeout(fn, 0) 的用法,感到有些疑惑,不明白它和直接執行 fn() 有什么區別,遂去搜集了一下相關的資料,順便分享分享。

 

先看一段代碼:

function a() {
setTimeout( function(){
alert(1)
}, 0);
alert(2);
}
a();

代碼中的 setTimeout 設為 0,也就是延遲 0ms,看上去是不做任何延遲立刻執行,即依次彈出 “1”、“2”。但實際的執行結果確是 “2”、“1”。其中的原因得從 setTimeout 的原理說起:

JavaScript 是單線程執行的,也就是無法同時執行多段代碼,當某一段代碼正在執行的時候,所有后續的任務都必須等待,形成一個隊列,一旦當前任務執行完畢,再從隊列中取出下一個任務。這也常被稱為 “阻塞式執行”。所以一次鼠標點擊,或是計時器到達時間點,或是 Ajax 請求完成觸發了回調函數,這些事件處理程序或回調函數都不會立即運行,而是立即排隊,一旦線程有空閑就執行。假如當前 JavaScript 進程正在執行一段很耗時的代碼,此時發生了一次鼠標點擊,那么事件處理程序就被阻塞,用戶也無法立即看到反饋,事件處理程序會被放入任務隊列,直到前面的代碼結束以后才會開始執行。如果代碼中設定了一個 setTimeout,那么瀏覽器便會在合適的時間,將代碼插入任務隊列,如果這個時間設為 0,就代表立即插入隊列,但不是立即執行,仍然要等待前面代碼執行完畢。所以setTimeout 並不能保證執行的時間,是否及時執行取決於 JavaScript 線程是擁擠還是空閑。

 

至於這樣的寫法有什么作用,看下面的例子。

<input type="text" onkeydown="show(this.value)">
<div></div>
<script type="text/javascript">
function show(val) {
document.getElementsByTagName('div')[0].innerHTML = val;
}
</script>

這里綁定了 keydown 事件,意圖是當用戶在文本框里輸入字符時,將輸入的內容實時地在 <div> 中顯示出來。但是實際效果並非如此

可以發現,每按下一個字符時,<div> 中只能顯示出之前的內容,無法得到當前的字符。這時就可以利用 setTimeout(0)

原因是,當用戶按下按鍵的時候,JavaScript 引擎需要執行 keydown 的事件處理程序,然后更新文本框的 value 值,這兩件事也需要按順序來,事件處理程序執行時,更新 value 值的任務則進入隊列等待。所以我們在 keydown 的事件處理程序里是無法得到更新后的 value 的,利用 setTimeout,我們把取 value 的操作放入隊列,放在更新 value 值以后,這樣便達到了目的。示例如下,可以發現已經能夠實時顯示輸入的內容。

 

 

有人可能會想到利用綁定 keyup 事件來解決,但是 onkeyup 有一個問題,就是當一直按着某個鍵不放時,也會無法得到輸入內容,因為此時不斷地觸發keydown 和 keypress,直到用戶松起時才會觸發 keyup。當然,示例所用的keydown 也存在一些小缺點,比如用戶如果使用右鍵粘貼,則無法得到粘貼的內容。

所以最理想的方案應該是使用 HTML5 的 input 事件,當文本框或 textarea 的value 發生變化時,就會觸發此事件,對粘貼也可以很好地兼容。至於 IE9 之前的瀏覽器,需要使用專有的 onpropertychange 事件。

 

settimeout(0)就起到了一個將事件加入到隊列中,待執行的一個功能效果!

本文來自 小星_day 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/xingxing1828/article/details/28424591?utm_source=copy 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM