認識延遲時間為0的setTimeout
更新時間:2008年05月16日 22:44:39 作者:
由 John Resig 的 How JavaScript Timers Work 可以知道,現(xiàn)有的 JavaScript 引擎是單線程處理任務(wù)的。它把任務(wù)放到隊列中,不會同步去執(zhí)行,必須在完成一個任務(wù)后才開始另外一個任務(wù)。
讓我們看看我之前的文章:JavaScript的9個陷阱及評點,在第 9 點 Focus Pocus 中提到的問題。原作者對這個認識有所偏差,其實不只是 IE 的問題,而是現(xiàn)有 JavaScript 引擎對于線程實現(xiàn)的問題(關(guān)于線程,我的概念其實不多,如果不對,希望讀者多多指教)。. 我們來看 1 和 2。如果你能看看源代碼,會發(fā)現(xiàn)我們的任務(wù)很簡單,就是給文檔增加一個 input 文本框,并聚焦和選中。請現(xiàn)在分別點擊一下,可以看到,1 并沒有能夠聚焦和選中,而 2 可以。它們之間的區(qū)別在于,在執(zhí)行:
input.focus();
input.select();
時, 2 多了一個延遲時間為 0 的 setTimeout 的外圍函數(shù),即:
setTimeout(function(){
input.focus();
input.select();
}, 0);
按照 JavaScript: The Definitive Guide 5th 的 14.1 所說:
在實踐中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執(zhí)行,以及完成文檔當前狀態(tài)更新后,告訴瀏覽器去啟用 setTimeout 內(nèi)注冊的函數(shù)。
其實,這是一個把需要執(zhí)行的任務(wù)從隊列中跳脫的技巧?;氐角懊娴睦?,JavaScript 引擎在執(zhí)行 onkeypress 時,由于沒有多線程的同步執(zhí)行,不可能同時去處理剛創(chuàng)建元素的 focus 和 select 事件,由于這兩個事件都不在隊列中,在完成 onkeypress 后,JavaScript 引擎已經(jīng)丟棄了這兩個事件,正如你看到的例子 1 的情況。而在例子 2 中,由于setTimeout可以把任務(wù)從某個隊列中跳脫成為新隊列,因而能夠得到期望的結(jié)果。
這才是延遲事件為 0 的setTimeout的真正目的。在此,你可以看看例子 3,它的任務(wù)是實時更新輸入的文本,現(xiàn)在請試試,你會發(fā)現(xiàn)預(yù)覽區(qū)域總是落后一拍,比如你輸 a, 預(yù)覽區(qū)并沒有出現(xiàn) a, 在緊接輸入 b 時, a 才不慌不忙地出現(xiàn)。其實我們是有辦法讓預(yù)覽區(qū)跟輸入框同步地,在此我沒有給出答案,因為上面所說的,就是解決思路,try it yourself!
input.focus();
input.select();
時, 2 多了一個延遲時間為 0 的 setTimeout 的外圍函數(shù),即:
setTimeout(function(){
input.focus();
input.select();
}, 0);
按照 JavaScript: The Definitive Guide 5th 的 14.1 所說:
在實踐中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執(zhí)行,以及完成文檔當前狀態(tài)更新后,告訴瀏覽器去啟用 setTimeout 內(nèi)注冊的函數(shù)。
其實,這是一個把需要執(zhí)行的任務(wù)從隊列中跳脫的技巧?;氐角懊娴睦?,JavaScript 引擎在執(zhí)行 onkeypress 時,由于沒有多線程的同步執(zhí)行,不可能同時去處理剛創(chuàng)建元素的 focus 和 select 事件,由于這兩個事件都不在隊列中,在完成 onkeypress 后,JavaScript 引擎已經(jīng)丟棄了這兩個事件,正如你看到的例子 1 的情況。而在例子 2 中,由于setTimeout可以把任務(wù)從某個隊列中跳脫成為新隊列,因而能夠得到期望的結(jié)果。
這才是延遲事件為 0 的setTimeout的真正目的。在此,你可以看看例子 3,它的任務(wù)是實時更新輸入的文本,現(xiàn)在請試試,你會發(fā)現(xiàn)預(yù)覽區(qū)域總是落后一拍,比如你輸 a, 預(yù)覽區(qū)并沒有出現(xiàn) a, 在緊接輸入 b 時, a 才不慌不忙地出現(xiàn)。其實我們是有辦法讓預(yù)覽區(qū)跟輸入框同步地,在此我沒有給出答案,因為上面所說的,就是解決思路,try it yourself!
相關(guān)文章
javascript異步編程代碼書寫規(guī)范Promise學(xué)習(xí)筆記
這篇文章主要介紹了javascript異步編程代碼書寫規(guī)范Promise學(xué)習(xí)筆記,需要的朋友可以參考下2015-02-02前端學(xué)習(xí)筆記style,currentStyle,getComputedStyle的用法與區(qū)別
這篇文章主要介紹了前端學(xué)習(xí)筆記style,currentStyle,getComputedStyle的用法與區(qū)別,需要的朋友可以參考下2016-05-05javascript判斷ie瀏覽器6/7版本加載不同樣式表的實現(xiàn)代碼
ie6/ie7的兼容問題很讓人苦惱,我們可以針對這兩個版本的瀏覽器單獨寫?yīng)毩⒌臉邮奖?,來解決兼容問題。這里的例子以判斷ie6與ie7來加載不同的樣式表2011-12-12在layui.use 中自定義 function 的正確方法
今天小編就為大家分享一篇在layui.use 中自定義 function 的正確方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09js實現(xiàn)樹形數(shù)據(jù)轉(zhuǎn)成扁平數(shù)據(jù)的方法示例
這篇文章主要介紹了js實現(xiàn)樹形數(shù)據(jù)轉(zhuǎn)成扁平數(shù)據(jù)的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02用javascript實現(xiàn)無刷新更新數(shù)據(jù)的詳細步驟 asp
用javascript實現(xiàn)無刷新更新數(shù)據(jù)的詳細步驟 asp...2006-12-12微信小程序使用GoEasy實現(xiàn)websocket實時通訊
這篇文章主要介紹了微信小程序使用GoEasy實現(xiàn)websocket實時通訊的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05