NodeJS入門篇

  在我印象裏,「全棧工程師」這個詞是NodeJS誕生後才逐漸火起來的,由於NodeJS賦予了JS服務器開發的能力。下面開始從一個小白的角度進軍NodeJS...php

  前言:在學習NodeJS以前是須要安裝的,安裝方法很easy。安裝好以後,安裝路徑會自動寫到環境變量path路徑中,因此咱們能夠直接cmd去黑窗口用node命令運行js文件。html

一、NodeJS是什麼

  Node.js是一個構建在Chrome V8引擎上的 JavaScript 運行環境。java

   此時,JS的運行環境就多了一個,變成倆個了——瀏覽器、NodeJS。安裝完node以後,咱們就能夠用node命令去執行js文件。好比node demo.js命令去執行一個demo.js文件...node

二、NodeJS的特色

  單線程、非阻塞異步I/O、事件驅動   web

 

  一、js是單線程執行的

  也就是說,同一個時間只能作一件事,不像java、php那樣能夠建立多個線程,這是js的特色。express

  在Java、PHP或者.net等服務器語言中,會爲每一個客戶端鏈接建立一個新的進程。而每一個進程須要耗費大約2MB內存。也就是說,理論上一個8GB的服務器能夠同時鏈接最大用戶量爲4000個左右。要讓Web應用程序同時支持更多的用戶,就須要增長服務器的數量或內存數,這樣硬件成本就上升了。npm

  NodeJS不爲每一個客戶鏈接建立一個新的線程,而僅僅使用一個線程。當有用戶鏈接,就觸發一個內部事件,經過非阻塞I/0、事件驅動機制,讓NodeJS程序宏觀上也是並行的,給人的感受就是用戶之間互不影響。使用NodeJS,一個8GB內存服務器,能夠同時處理超過4萬用戶的鏈接。編程

  另外,單線程帶來的好處還有操做系統徹底再也不有線程建立、銷燬的時間開銷。json

 

  二、非阻塞異步I/O

  簡單點說就死異步不會阻塞後面的代碼。絕大多數網站的I/O操做不少,I就是input數據的讀取,O就是output數據的寫入。可是I/O的時候,CPU命令磁盤去作事情,CPU就閒置了。瀏覽器

  

  三、事件驅動模型:NodeJS底層機制,保證不會「上錯菜」

  

  

主線程:主線程會一直輪詢,隊列中沒有代碼了,主線程就會退出。

  1.執行node的代碼,把代碼放入隊列
  2.事件循環程序(主線程)把隊列裏面的同步代碼都先執行了,
  3.同步代碼執行完成,執行異步代碼
  4.異步代碼分2種情況,    

    1.異步非io setTimeout() setInterval(),判斷是否可執行,若是能夠執行就執行,不能夠跳過。

    2.異步io 文件操做 會從線程池當中去取一條線程,幫助主線程去執行。

 

子線程:被放在線程池裏面的線程,用來執行異步io操做

  1.在線程池裏休息
  2.異步io的操做來了,執行異步io操做。
  3.子線程會把異步io操做的callback函數,扔回給隊列
  4.子線程會回到線程池了去休息。

 

回調(callback ):在異步io代碼執行完成的時候被扔回主線程。

三、NodeJS組成

  1. 引入 required 模塊:咱們可使用 require 指令來載入 Node.js 模塊。
  2. 建立服務器:服務器能夠監聽客戶端的請求,相似於 Apache 、Nginx 等 HTTP 服務器。
  3. 接收請求與響應請求:服務器很容易建立,客戶端可使用瀏覽器或終端發送 HTTP 請求,服務器接收請求後返回響應數據。

四、建立第一個NodeJS應用

// 使用 require 指令來載入 http 模塊,並將實例化的 HTTP 賦值給變量 http
var http = require('http'); 

// 使用 http.createServer() 方法建立服務器,並使用 listen 方法綁定 3000端口。 函數經過 request, response 參數來接收和響應數據
http.createServer(function (request, response) {

    // 發送 HTTP 頭部 
    // HTTP 狀態值: 200 : OK
    // 內容類型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});

    // 發送響應數據 "Hello World"
    response.end('Hello World\n');
}).listen(3000);

// 終端打印以下信息
console.log('Server running at http://127.0.0.1:3000/');

 把以上代碼放到單獨某個js文件中,用node命令去執行,便會在本地建立一個端口號爲3000的服務器。

五、NPM介紹使用

NPM是隨同NodeJS一塊兒安裝的包管理工具,能解決NodeJS代碼部署上的不少問題,常見的使用場景有如下幾種:
-- 容許用戶從NPM服務器下載別人編寫的第三方包到本地使用。
-- 容許用戶從NPM服務器下載並安裝別人編寫的命令行程序到本地使用。
-- 容許用戶將本身編寫的包或命令行程序上傳到NPM服務器供別人使用。

 

一、使用npm命令安裝模塊  $ npm install <Module Name> 

好比:npm 命令安裝經常使用的 Node.js web框架模塊 express: $ npm install express 安裝好以後,express 包就放在了工程目錄下的 node_modules 目錄中。所以在代碼中只須要經過 require('express') 的方式就好,無需指定第三方包路徑。引用方式: var express = require('express'); 

二、全局安裝和本地安裝:npm 的包安裝分爲本地安裝(local)、全局安裝(global)兩種,從敲的命令行來看,差異只是有沒有-g而已,好比:

npm install express      # 本地安裝
npm install express -g   # 全局安裝

 

本地安裝
  1. 將安裝包放在 ./node_modules 下(運行 npm 命令時所在的目錄),若是沒有 node_modules 目錄,會在當前執行 npm 命令的目錄下生成 node_modules 目錄。
  2. 能夠經過 require() 來引入本地安裝的包。


全局安裝
  1. 將安裝包放在 /usr/local 下或者你 node 的安裝目錄。
  2. 能夠直接在命令行裏使用。

 

三、建立模塊package.json 文件是必不可少的。咱們可使用 NPM 生成 package.json 文件

六、回調函數

Node.js 異步編程的直接體現就是回調
異步編程依託於回調來實現,但不能說使用了回調後程序就異步化了。
回調函數在完成任務後就會被調用,Node 使用了大量的回調函數,Node 全部 API 都支持回調函數
例如,咱們能夠一邊讀取文件,一邊執行其餘命令,在文件讀取完成後,咱們將文件內容做爲回調函數的參數返回。這樣在執行代碼時就沒有阻塞或等待文件 I/O 操做。這就大大提升了 Node.js 的性能,能夠處理大量的併發請求。

回調函數通常做爲函數的最後一個參數出現:

function foo1(name, age, callback) { };
function foo2(value, callback1, callback2) { }

 

阻塞代碼實例:

// 引入文件操做模塊
var fs = require("fs");

var data = fs.readFileSync('input.txt'); //input.txt內容是: 我是input.txt內容

console.log(data.toString());
console.log("程序執行結束!");

// 用node命令執行
$ node main.js
我是input.txt內容
程序執行結束!

 

非阻塞代碼實例:

// 引入文件操做模塊
var fs = require("fs");
fs.readFile('input.txt', function (err, data) { 
  if (err) return console.error(err); console.log(data.toString());
});
console.log(
"程序執行結束!");

// 用node命令執行
$ node main.js
程序執行結束
!
我是input.txt內容

 

第一個實例在文件讀取完後才執行完程序。

第二個實例咱們不須要等待文件讀取完,這樣就能夠在讀取文件時同時執行接下來的代碼,大大提升了程序的性能。

所以,阻塞是按順序執行的,而非阻塞是不須要按順序的,因此若是須要處理回調函數的參數,咱們就須要寫在回調函數內。

 

參考:https://www.runoob.com/nodejs/nodejs-event-loop.html

相關文章
相關標籤/搜索