国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Node.js事件循環(Event Loop)和線程池詳解

2019-11-20 13:17:57
字體:
來源:轉載
供稿:網友

Node的“事件循環”(Event Loop)是它能夠處理大并發、高吞吐量的核心。這是最神奇的地方,據此Node.js基本上可以理解成“單線程”,同時還允許在后臺處理任意的操作。這篇文章將闡明事件循環是如何工作的,你也可以感受到它的神奇。

事件驅動編程

理解事件循環,首先要理解事件驅動編程(Event Driven Programming)。它出現在1960年。如今,事件驅動編程在UI編程中大量使用。JavaScript的一個主要用途是與DOM交互,所以使用基于事件的API是很自然的。

簡單地定義:事件驅動編程通過事件或狀態的變化來進行應用程序的流程控制。一般通過事件監聽實現,一旦事件被檢測到(即狀態改變)則調用相應的回調函數。聽起來很熟悉?其實這就是Node.js事件循環的基本工作原理。

如果你熟悉客戶端JavaScript的開發,想一想那些.on*()方法,如element.onclick(),他們用來與DOM元素相結合,傳遞用戶交互。這個工作模式允許在單個實例上觸發多個事件。Node.js通過EventEmitter(事件發生器)觸發這種模式,如在服務器端的Socket和 “http”模塊中。可以從一個單一實例觸發一種或一種以上的狀態改變。

另一種常見的模式是表達成功succeed和失敗fail。現在一般有兩種常見的實現方式。首先是將“Error異常”傳入回調,一般作為第一個參數傳遞給回調函數。第二種即使用Promises設計模式,已經加入了ES6。注* Promise模式采用類似jQuery的函數鏈式書寫方式,以避免深層次的回調函數嵌套,如:

復制代碼 代碼如下:

$.getJSON('/getUser').done(successHandler).fail(failHandler)

“fs”(filesystem)模塊大多采用往回調中傳入異常的風格。在技術上觸發某些調用,例如fs.readFile()附加事件,但該API只是為了提醒用戶,用來表達操作成功或失敗。選擇這樣的API是出于架構的考慮,而非技術的限制。

一個常見的誤解是,事件發生器(event emitters)在觸發事件時也是天生異步的,但這是不正確的。下面是一個簡單的代碼片段,以證明這一點。

復制代碼 代碼如下:

function MyEmitter() {
  EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter);

MyEmitter.prototype.doStuff = function doStuff() {
  console.log('before')
  emitter.emit('fire')
  console.log('after')}
};

var me = new MyEmitter();
me.on('fire', function() {
  console.log('emit fired');
});

me.doStuff();
// 輸出:
// before
// emit fired
// after

注* 如果 emitter.emit 是異步的,則輸出應該為
// before
// after
// emit fired


EventEmitter經常表現地很異步,因為它經常用于通知需要異步完成的操作,但EventEmitter API本身是完全同步的。監聽函數內部可以按異步執行,但請注意,所有的監聽函數將按被添加的順序同步執行。

機制概述和線程池

Node本身依賴多個庫。其中之一是libuv,神奇的處理異步事件隊列和執行的庫。

Node利用盡可能多的利用操作系統內核實現現有的功能。像生成響應請求(request),轉發連接(connections)并委托給系統處理。例如,傳入的連接通過操作系統進行隊列管理,直到它們可以由Node處理。

您可能聽說過,Node有一個線程池,你可能會疑惑:“如果Node會按次序處理任務,為什么還需要一個線程池?”這是因為在內核中,不是所有任務都是按異步執行的。在這種情況下,Node.JS必須能在操作時將線程鎖定一段時間,以便它可以繼續執行事件循環而不會被阻塞。

下面是一個簡單的示例圖,來表示他內部的運行機制:


            ┌───────────────────────┐

主站蜘蛛池模板: 乌鲁木齐县| 乌恰县| 兴宁市| 大同市| 彩票| 阿拉善右旗| 彭阳县| 淮安市| 象州县| 鄂托克旗| 仲巴县| 长白| 正阳县| 海门市| 和林格尔县| 尉氏县| 区。| 阜新市| 尖扎县| 布尔津县| 青田县| 龙南县| 邯郸县| 巨鹿县| 九寨沟县| 田林县| 宜昌市| 北安市| 墨江| 余庆县| 武安市| 洞头县| 始兴县| 酉阳| 普格县| 大埔县| 榆树市| 绥宁县| 宝山区| 甘泉县| 米易县|