1. 程式人生 > >node 你到底懂多少,等你,來~~

node 你到底懂多少,等你,來~~

Node能夠解決什麼問題?

Node的首要目標是提供一種簡單的,用於建立高效能伺服器的開發工具 Web伺服器的瓶頸在於併發的使用者量,對比Java和Php的實現方式

Node在處理高併發,I/O密集場景有明顯的效能優勢

  • 高併發,是指在同一時間併發訪問伺服器
  • I/O密集指的是檔案操作、網路操作、資料庫,相對的有CPU密集,CPU密集指的是邏輯處理運算、壓縮、解壓、加密、解密

其實node 火爆最大的原因是前端的火爆,前端後重視後,在的大前端的大潮中推向頂峰,因為Web主要場景就是接收客戶端的請求讀取靜態資源和渲染介面,所以Node非常適合Web應用的開發

Node是什麼?

Node.js是一個基於 Chrome V8 引擎的JavaScript執行環境(runtime),Node 不是一門語言 是讓js執行在後端的執行時,並且不包括javascript全集,因為在服務端中不包含DOM和BOM,Node也提供了一些新的模組例如http,fs模組等。Node.js 使用了事件驅動、非阻塞式 I/O 的模型,使其輕量又高效並且Node.js 的包管理器 npm,是全球最大的開源庫生態系統。

我個人對node的事件輪詢的理解是這樣的,主執行緒分配任務下去,註冊回撥函式。主執行緒裡在執行程式碼的時候io繼續等待,主執行緒執行完畢後進行輪詢,因為這個時候主執行緒是空閒狀態,所以可以一直輪詢,直到發現有某一個io操作給他發了訊號告訴他我現在弄好了,你可以用這個資料,主執行緒的資源就拿來執行回撥函式。也就是說從始至終都只有主執行緒在做事情,主執行緒要不然是在執行函式,要不然就是在進行事件的輪詢,去尋找有哪個事件完成了需要執行他的回撥函式。

大概就是所謂的單執行緒非同步吧

當然很多童鞋可能會問,為什麼js是單執行緒, javascript在最初設計時設計成了單執行緒,如果多個執行緒同時操作DOM那豈不會很混亂?這裡所謂的單執行緒指的是主執行緒是單執行緒的,所以在Node中主執行緒依舊是單執行緒的。

順便扯一下程序與執行緒

來一張圖關於瀏覽器的

  • 使用者介面-包括位址列、前進/後退按鈕、書籤選單等
  • 瀏覽器引擎-在使用者介面和呈現引擎之間傳送指令(瀏覽器的主程序)
  • 渲染引擎,也被稱為瀏覽器核心(瀏覽器渲染程序)

本人查了一些資料,其實渲染引擎內部是多執行緒的,內部包含兩個最為重要的執行緒ui執行緒和js執行緒。這裡要特別注意ui執行緒和js執行緒是互斥的,因為JS執行結果會影響到ui執行緒的結果。ui更新會被儲存在佇列中等到js執行緒空閒時立即被執行。

其他執行緒就是涉及事件迴圈(Event Loop),大家可以自行谷歌。

關於buffer

其實就是相當於我們js陣列理解就可以了,那為什麼node需要用buffer表示。 緩衝區Buffer是暫時存放輸入輸出資料的一段記憶體。 JS語言沒有二進位制資料型別,而在處理TCP和檔案流的時候,必須要處理二進位制資料。 貌似es6也出了一個TypedArray,應該是差不多的。

node官網buffer機票

node的可讀流和可寫流

之前寫的,現在基本忘記了~~ 流相關-機票

let http = require('http');
//req 流物件 是可讀流
//res 是一個可寫流 write
let server = http.createServer();
let url = require('url');
//當客戶端連線上伺服器之後執行回撥
server.on('connection', function () {
    console.log('客戶端連線 ');
});
//req代表客戶端的連線,server伺服器把客戶端的請求資訊進行解析,然後放在req上面
//res代表響應,如果希望向客戶端迴應訊息,需要通過 res
server.on('request', function (req, res) {
    console.log(req.method);//獲取請求方法名
    let { pathname, query } = url.parse(req.url, true);
    console.log(pathname);
    console.log(query);
    console.log(req.url);//獲取請求路徑 
    console.log(req.headers);//請求頭物件
    let result = [];
    req.on('data', function (data) {
        result.push(data);
    });
    req.on('end', function () {
        let r = Buffer.concat(result);//請求體
        console.log(r.toString());
        //如果進行響應

        res.end(r);
    })
});
server.on('close', function (req, res) {
    console.log('伺服器關閉 ');
});
server.on('error', function (err) {
    console.log('伺服器錯誤 ');
});
server.listen(8089, function () {
    console.log('server started at http://localhost:8089');
});
複製程式碼