您好,登錄后才能下訂單哦!
這篇文章主要介紹“javascript的事件驅動機制是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“javascript的事件驅動機制是什么”文章能幫助大家解決問題。
javascript采用事件驅動。JavaScript是一種基于對象和事件驅動并具有安全性能的腳本語言,它采用事件驅動的機制來響應用戶操作,當用戶對某個html元素進行操作的時候,會產生一個事件,該事件會驅動某些函數來處理。
本教程操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
JavaScript是一種基于對象和事件驅動并具有安全性能的腳本語言。
本文分別講解了javascript在瀏覽器端和服務器端(node.js)的事件驅動機制,期間加入了一些異步編程的例子加深理解。
javascript 在瀏覽器端的事件驅動機制
首先,javascript 在瀏覽器端運行是單線程的,這是由瀏覽器決定的,這是為了避免多線程執行不同任務會發生沖突的情況。也就是說我們寫的javascript 代碼只在一個線程上運行,稱之為主線程(HTML5提供了web worker API可以讓瀏覽器開一個線程運行比較復雜耗時的 javascript任務,但是這個線程仍受主線程的控制)。單線程的話,如果我們做一些“sleep”的操作比如說:
var now = + new Date()while (+new Date() <= now + 1000){ //這是一個耗時的操所 }
那么在這將近一秒內,線程就會被阻塞,無法繼續執行下面的任務。
還有些操作比如說獲取遠程數據、I/O操作等,他們都很耗時,如果采用同步的方式,那么進程在執行這些操作時就會因為耗時而等待,就像上面那樣,下面的任務也只能等待,這樣效率并不高。 為了解決單線程帶來的阻塞問題很多操作系統實現了異步編程機制,瀏覽器中也是這么做的,主要表現如下:
只在主線程中運行 javascript 代碼
主線程一啟動就進入事件循環,整個過程就是不斷的循環,不斷地執行回調函數
遇到網絡請求、I/O操作等時,瀏覽器會單開工作線程來處理,并設置相應的觀察者,然后立即返回主線程,主線程繼續執行下面的任務
瀏覽器開的線程處理好任務或者有監聽的事件后會用得到的數據(或輸入)形成一個事件,放在相應觀察者的事件隊列中,事件隊列是在主線程中
主線程不斷的循環,不斷檢查事件隊列,通過遍歷事件依次執行事件對應的回調函數
注意:下圖中的消息隊列是存儲在主線程中
上圖中,假設你發起了一個AJAX請求,無論你把這個請求寫在什么地方,它始終都在回調函數里。因為事件驅動機制就是把一切抽象為事件,代碼開始執行也是一個事件,也會隱式調用回調函數,調用回調函數就是開始執行代碼。然后主線程發起異步任務后就會隨即返回,繼續執行"代碼開始事件"對應回調函數里下面的代碼,等到這個回調函數執行完畢,就會執行下一個事件。在這之間,Ajax線程會完成請求,然后把請求完成的事件(包含返回的數據)發送到事件隊尾中等待處理,等到主線程執行到這個事件時,指定的回調函數即被執行。
大概是這樣。如果有幾處疑問的話請往下看。下面結合代碼講一下具體的過程和機制。
console.log("開始");setTimeout(function(){ console.log('延遲執行的') }, 1000);setTimeout(function(){ console.log('立即執行的') }, 0); console.log('結束') //開始 結束 立即執行的 延遲執行的
watcher
機制
watcher
,觀察者,是事件驅動系統重要的機制。
setTimeout
稱為定時器,這是瀏覽器給的API。每當你使用定時器,這個函數將會設置一個watcher
,觀察者。主線程會不斷的循環,不斷的"經過"這里檢查時間,當主線程檢查時間間隔符合要求時,就會產生一個定時器事件,加入到這個watcher
事件隊列中并執行回調函數。因此執行setTimeout
只是在時間到的時候產生了要調用回調函數的消息加入到了事件隊列中,因此,回調函數并不一定在指定的時間時調用,它取決于前面有多少等待處理的事件。
剛才講的是定時器觀察者,還有I/O觀察者、網絡請求觀察者、鼠標事件觀察者、鍵盤事件觀察者等等等等,我們經常遇到事件監聽函數會讓你綁定一個回調函數,這種監聽函數一般就會設置watcher
,其他線程產生的事件也會放到相應watcher
的事件隊列中,因此每個watcher
會產生自己的事件隊列。主線程在循環的時候,實際上是在依次調用這些watcher
,檢查每個watcher
的事件隊列,有事件就執行相應的回調。
它的過程就是 :
進程一啟動就進入事件循環
有監聽就添加watcher
遍歷watcher
下的事件隊列
執行下一個watcher
事件驅動機制,它會有各種各樣的事件,大量的事件,它所做的一切都跟處理事件有關。但并不是所有的事件都有watcher
,如果都有,主進程任務會變得非常繁重,況且有些事件我們并不關心,例如你只寫了一個定時器,代表你關心這個事件,那么點擊事件、網絡請求事件就不用關心,因為你根本就沒寫啊,也就沒有watcher
。
javascript 在 node.js上的事件驅動機制
javascript 在 node.js上的事件驅動機制與瀏覽器端大致相同,都是單線程,都有event loop,上面講的javascript在瀏覽器端的事件循環機制在node上也是大致一樣的,不同的是執行者何執行者的行為不一樣,因為他們關注的任務不一樣:
node端異步機制和事件循環更加純粹一些。node為了支持高并發,所有的API幾乎都是異步的,這樣會充分利用操作系統的其他線程來幫忙完成任務,主線程只負責事件消費。例如當web server接收到請求,node就把它關閉,交給其他線程進行處理,然后去服務下一個web請求。當這個請求完成,它被放到處理隊列,當到達隊列開頭,這個結果被返回給用戶。這樣的話webserver一直接受請求而不等待任何讀寫操作,這種非阻塞型I/O性能很強。
瀏覽器端是瀏覽器負責執行BOM API,管理線程,處理用戶輸入信息等,在node上是node的一個核心庫libuv負責執行node API,管理主線程(運行javascript)和工作線程等。
因為前端和后端關注的內容不同,因此兩個運行環境的API也專注于不同的任務
關于“javascript的事件驅動機制是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。