關於javascript的事件執行機制理解


理解javascript事件執行機制

眾所周知,js是一個單線程的語言,這意味着同一時間只能做一件事,但是我們又說js是異步的。首先,單線程並不是沒有優點。作為瀏覽器腳本語言,JavaScript 的主要用途是與用戶互動,以及操作 DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。比如,假定JavaScript 同時有兩個線程,一個線程在某個 DOM 節點上添加內容,另一個線程刪除了這個節點,那最后應該以哪個為准呢? 所以,為了避免復雜性,從一誕生,JavaScript 就是單線程,這已經成了這門語言的核心特征,將來也不會改變。

實際上,主線程只會做一件事情,就是從消息隊列里面取消息、執行消息,再取消息、再執行。當消息隊列為空時,就會等待直到消息隊列變成非空。而且主線程只有在將當前的消息執行完成后,才會去取下一個消息。這種機制就叫做事件循環機制,取一個消息並執行的過程叫做一次循環 。就如圖所示一樣

 

如果說js只有一個主線程,那么它應該有三個輔助的子線程,分別為事件處理線程、http網絡請求線程、定時器處理線程。這些線程就是實現js異步的關鍵,比如主線程內有程序正在運行,這個時候后面有一個定時器在等待,那么主線程肯定不會檢測這個定時器的時間是否達到要求的,這樣會消耗性能和時間,所以就交給定時器處理線程,當setTimeout的時間達到時,它就會把這個定時器里的函數(其實這就是回調函數了)放到任務隊列里,當主線程把執行棧中的任務都執行完以后,執行棧為空了,就會從任務隊列里找,執行里面的回調,如此循環往復,這就是時間循環。由於執行任務還是只有一個主線程可以做,所以有時候即使定時器觸發的事件已經到了,但是它的回調函數也只能在任務隊列中等待,這導致最后函數觸發的事件往往比設置的時間長,這也是我們說定時器准確度不高的原因。


免責聲明!

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



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