javascript採用什麼驅動

2022-02-07 13:00:32

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操作等時,瀏覽器會單開工作執行緒來處理,並設定相應的觀察者,然後立即返回主執行緒,主執行緒繼續執行下面的任務

  • 瀏覽器開的執行緒處理好任務或者有監聽的事件後會用得到的資料(或輸入)形成一個事件,放在相應觀察者的事件佇列中,事件佇列是在主執行緒中

  • 主執行緒不斷的迴圈,不斷檢查事件佇列,通過遍歷事件依次執行事件對應的回撥函數

注意:下圖中的訊息佇列是儲存在主執行緒中

1.png

上圖中,假設你發起了一個AJAX請求,無論你把這個請求寫在什麼地方,它始終都在回撥函數裡。因為事件驅動機制就是把一切抽象為事件,程式碼開始執行也是一個事件,也會隱式呼叫回撥函數,呼叫回撥函數就是開始執行程式碼。然後主執行緒發起非同步任務後就會隨即返回,繼續執行"程式碼開始事件"對應回撥函數裡下面的程式碼,等到這個回撥函數執行完畢,就會執行下一個事件。在這之間,Ajax執行緒會完成請求,然後把請求完成的事件(包含返回的資料)傳送到事件隊尾中等待處理,等到主執行緒執行到這個事件時,指定的回撥函數即被執行。

大概是這樣。如果有幾處疑問的話請往下看。下面結合程式碼講一下具體的過程和機制。

console.log("開始");setTimeout(function(){
  console.log('延遲執行的')
}, 1000);setTimeout(function(){
  console.log('立即執行的')
}, 0);
console.log('結束') //開始 結束 立即執行的 延遲執行的

watcher機制

watcher,觀察者,是事件驅動系統重要的機制。

setTimeout稱為定時器,這是瀏覽器給的API。每當你使用定時器,這個函數將會設定一個watcher,觀察者。主執行緒會不斷的迴圈,不斷的"經過"這裡檢查時間,當主執行緒檢查時間間隔符合要求時,就會產生一個定時器事件,加入到這個watcher事件佇列中並執行回撥函數。因此執行setTimeout只是在時間到的時候產生了要呼叫回撥函數的訊息加入到了事件佇列中,因此,回撥函數並不一定在指定的時間時呼叫,它取決於前面有多少等待處理的事件。

2.png

剛才講的是定時器觀察者,還有I/O觀察者、網路請求觀察者、滑鼠事件觀察者、鍵盤事件觀察者等等等等,我們經常遇到事件監聽函數會讓你係結一個回撥函數,這種監聽函數一般就會設定watcher,其他執行緒產生的事件也會放到相應watcher的事件佇列中,因此每個watcher產生自己的事件佇列主執行緒在迴圈的時候,實際上是在依次呼叫這些watcher,檢查每個watcher的事件佇列,有事件就執行相應的回撥。

3.png

它的過程就是 :

  • 程序一啟動就進入事件迴圈

  • 有監聽就新增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採用什麼驅動的詳細內容,更多請關注TW511.COM其它相關文章!