setTimeOut設(shè)置為0,會(huì)在隊(duì)列最后添加一個(gè)事件棠赛,要等待其他任務(wù)事件處理完成才會(huì)處理挖滤。
js EventLoop詳見EventLoop
延遲的毫秒數(shù) (一秒等于 1000 毫秒)剪撬,函數(shù)的調(diào)用會(huì)在該延遲之后發(fā)生。如果省略該參數(shù),delay 取默認(rèn)值 0筷狼,意味著“馬上”執(zhí)行动看,或者盡快執(zhí)行。不管是哪種情況洞慎,實(shí)際的延遲時(shí)間可能會(huì)比期待的 (delay 毫秒數(shù)) 值長痛单,
setTimeout的最小延遲時(shí)間問題:
有很多因素會(huì)導(dǎo)致 setTimeout 的回調(diào)函數(shù)執(zhí)行比設(shè)定的預(yù)期值更久,一般來說最小延時(shí) >=4ms劲腿。
具體原因:
1旭绒、在瀏覽器中,setTimeout/setInterval的每調(diào)用一次定時(shí)器的最小間隔是 4ms焦人,這通常是由于函數(shù)嵌套導(dǎo)致(嵌套層級(jí)達(dá)到一定深度)挥吵,或者是由于已經(jīng)執(zhí)行的 setInterval 的回調(diào)函數(shù)阻塞導(dǎo)致的。例如:
function cb() { f(); setTimeout(cb, 0); }
setTimeout(cb, 0);
setInterval(f, 0);
在 Chrome 和 Firefox 中花椭, 定時(shí)器的第 5 次調(diào)用被阻塞了忽匈;在 Safari 是在第 6 次;Edge 是在第 3 次矿辽。Gecko 從這個(gè)版本 version 56開始對(duì) setInterval() 開始采用這樣的機(jī)制
一直以來丹允,不同瀏覽器中出現(xiàn)這種最小延遲的情況有所不同(例如 Firefox)- 從其他地方調(diào)用了 setInterval( ),或者在嵌套函數(shù)調(diào)用 setTimeout( ) 時(shí)(嵌套級(jí)別達(dá)到特定深度時(shí))袋倔,都會(huì)出現(xiàn)超時(shí)延遲嫌松。
2、超時(shí)延遲
除了"最小延時(shí)"之外奕污,定時(shí)器仍然有可能因?yàn)楫?dāng)前頁面(或者操作系統(tǒng)/瀏覽器本身)被其他任務(wù)占用導(dǎo)致延時(shí)萎羔。 需要被強(qiáng)調(diào)是, 直到調(diào)用 setTimeout()的主線程執(zhí)行完其他任務(wù)之后碳默,回調(diào)函數(shù)和代碼段才能被執(zhí)行贾陷。例如
function foo() {
console.log('foo has been called');
}
setTimeout(foo, 0);
console.log('After setTimeout');
會(huì)在控制臺(tái)輸出:
After setTimeout
foo has been called
出現(xiàn)這個(gè)結(jié)果的原因是,盡管setTimeout 以 0ms 的延遲來調(diào)用函數(shù)嘱根,但這個(gè)任務(wù)已經(jīng)被放入了隊(duì)列中并且等待下一次執(zhí)行髓废;并不是立即執(zhí)行;隊(duì)列中的等待函數(shù)被調(diào)用之前该抒,當(dāng)前代碼必須全部運(yùn)行完畢慌洪,因此這里運(yùn)行結(jié)果并非預(yù)想的那樣