javascript 任務執行的內幕

來源:互聯網
上載者:User

由 John Resig 的 How JavaScript Timers Work 可以知道,現有的 JavaScript 引擎是單線程處理任務的。它把任務放到隊列中,不會同步去執行,必須在完成一個任務後才開始另外一個任務。

讓我們看看我之前的文章:JavaScript的9個陷阱及評點,在第 9 點 Focus Pocus 中提到的問題。原作者對這個認識有所偏差,其實不只是 IE 的問題,而是現有 JavaScript 引擎對於線程實現的問題(關於線程,我的概念其實不多,如果不對,希望讀者多多指教)。我們通過一個例子來說明,請訪問 http://realazy.org/lab/settimeout.html. 我們來看 1 和 2。如果你能看看原始碼,會發現我們的任務很簡單,就是給文檔增加一個 input 文字框,並聚焦和選中。請現在分別點擊一下,可以看到,1 並沒有能夠聚焦和選中,而 2 可以。它們之間的區別在於,在執行:

Webjx.Com

input.focus();
input.select();
 

時, 2 多了一個延遲時間為 0 的 setTimeout 的外圍函數,即:

 

setTimeout(function(){
 input.focus();
 input.select();
}, 0);
 

按照 JavaScript: The Definitive Guide 5th 的 14.1 所說:

在實踐中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執行,以及完成文檔目前狀態更新後,告訴瀏覽器去啟用 setTimeout 內註冊的函數。 網頁教學網

其實,這是一個把需要執行的任務從隊列中跳脫的技巧。回到前面的例子,JavaScript 引擎在執行 onkeypress 時,由於沒有多線程的同步執行,不可能同時去處理剛建立元素的 focus 和 select 事件,由於這兩個事件都不在隊列中,在完成 onkeypress 後,JavaScript 引擎已經丟棄了這兩個事件,正如你看到的例子 1 的情況。而在例子 2 中,由於setTimeout可以把任務從某個隊列中跳脫成為新隊列,因而能夠得到期望的結果。

Webjx.Com

這才是延遲事件為 0 的setTimeout的真正目的。在此,你可以看看例子 3,它的任務是即時更新輸入的文本,現在請試試,你會發現預覽地區總是落後一拍,比如你輸 a, 預覽區並沒有出現 a, 在緊接輸入 b 時, a 才不慌不忙地出現。其實我們是有辦法讓預覽區跟輸入框同步地,在此我沒有給出答案,因為上面所說的,就是解決思路,try it yourself! Webjx

本文來自:網頁教學網(www.webjx.com)原文連結:http://www.webjx.com/javascript/jsajax-5207.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.