1.JavaScript中的setTimeout()可用來延遲執(zhí)行一段代碼闲坎,如:
setTimeout(function() {
? ? ? ? alert("Hello?World");
},?1000)//延時(shí)1秒
2.今天在網(wǎng)上看到了setTimeout(fn, 0)的用法值漫,感到有些疑惑,不明白它和直接執(zhí)行fn()有什么區(qū)別柑潦,遂去搜集了一下相關(guān)的資料,順便分享分享。
functiona() {
? ? ? ?setTimeout(function(){
? ? ? ? alert(1)
},?0);
alert(2);
}
a();
代碼中的setTimeout設(shè)為 0鹃答,也就是延遲 0ms干厚,看上去是不做任何延遲立刻執(zhí)行李滴,即依次彈出 “1”、“2”蛮瞄。但實(shí)際的執(zhí)行結(jié)果確是 “2”所坯、“1”。其中的原因得從setTimeout的原理說起:
javascript是單線程執(zhí)行的挂捅,也就是無法同時(shí)執(zhí)行多段代碼芹助,當(dāng)某一段代碼正在執(zhí)行的時(shí)候,所有后續(xù)的任務(wù)都必須等待闲先,形成一個(gè)隊(duì)列状土,一旦當(dāng)前任務(wù)執(zhí)行完畢,再從隊(duì)列中取出下一個(gè)任務(wù)饵蒂。這也常被稱為 “阻塞式執(zhí)行”声诸。所以一次鼠標(biāo)點(diǎn)擊,或是計(jì)時(shí)器到達(dá)時(shí)間點(diǎn)退盯,或是 Ajax 請(qǐng)求完成觸發(fā)了回調(diào)函數(shù)彼乌,這些事件處理程序或回調(diào)函數(shù)都不會(huì)立即運(yùn)行泻肯,而是立即排隊(duì),一旦線程有空閑就執(zhí)行慰照。假如當(dāng)前 JavaScript 進(jìn)程正在執(zhí)行一段很耗時(shí)的代碼灶挟,此時(shí)發(fā)生了一次鼠標(biāo)點(diǎn)擊,那么事件處理程序就被阻塞毒租,用戶也無法立即看到反饋稚铣,事件處理程序會(huì)被放入任務(wù)隊(duì)列,直到前面的代碼結(jié)束以后才會(huì)開始執(zhí)行墅垮。如果代碼中設(shè)定了一個(gè)setTimeout惕医,那么瀏覽器便會(huì)在合適的時(shí)間,將代碼插入任務(wù)隊(duì)列算色,如果這個(gè)時(shí)間設(shè)為 0抬伺,就代表立即插入隊(duì)列,但不是立即執(zhí)行灾梦,仍然要等待前面代碼執(zhí)行完畢峡钓。所以setTimeout并不能保證執(zhí)行的時(shí)間,是否及時(shí)執(zhí)行取決于 JavaScript 線程是擁擠還是空閑若河。
3.至于這樣的寫法有什么作用能岩,看下面的例子。
<input type="text" onkeydown="show(this.value)">
<div></div>
<script>
function show(val) {
? ? ? ? ? document.getElementsByTagName('div')[0].innerHTML = val;
}
</script>
這里綁定了keydown事件萧福,意圖是當(dāng)用戶在文本框里輸入字符時(shí)拉鹃,將輸入的內(nèi)容實(shí)時(shí)地在
可以發(fā)現(xiàn)统锤,每按下一個(gè)字符時(shí)毛俏,
原因是煌寇,當(dāng)用戶按下按鍵的時(shí)候,JavaScript 引擎需要執(zhí)行keydown的事件處理程序逾雄,然后更新文本框的value值阀溶,這兩件事也需要按順序來,事件處理程序執(zhí)行時(shí)鸦泳,更新value值的任務(wù)則進(jìn)入隊(duì)列等待银锻。所以我們?cè)趉eydown的事件處理程序里是無法得到更新后的value的,利用setTimeout做鹰,我們把取value的操作放入隊(duì)列击纬,放在更新value值以后,這樣便達(dá)到了目的钾麸。示例如下更振,可以發(fā)現(xiàn)已經(jīng)能夠?qū)崟r(shí)顯示輸入的內(nèi)容炕桨。
有人可能會(huì)想到利用綁定keyup事件來解決,但是onkeyup有一個(gè)問題肯腕,就是當(dāng)一直按著某個(gè)鍵不放時(shí)献宫,也會(huì)無法得到輸入內(nèi)容,因?yàn)榇藭r(shí)不斷地觸發(fā)keydown和keypress实撒,直到用戶松起時(shí)才會(huì)觸發(fā)keyup姊途。當(dāng)然,示例所用的keydown也存在一些小缺點(diǎn)知态,比如用戶如果使用右鍵粘貼捷兰,則無法得到粘貼的內(nèi)容。
所以最理想的方案應(yīng)該是使用HTML5的input事件肴甸,當(dāng)文本框或textarea的value發(fā)生變化時(shí)寂殉,就會(huì)觸發(fā)此事件,對(duì)粘貼也可以很好地兼容原在。至于 IE9 之前的瀏覽器,需要使用專有的onpropertychange事件彤叉。
settimeout(0)就起到了一個(gè)將事件加入到隊(duì)列中庶柿,待執(zhí)行的一個(gè)功能效果!