Node.js javascript
前言:
2009年面世
nodejs.org 官網
https://www.npmjs.com/ 模塊社區
github.com 倉庫
stackoverflow.com 問答社區
基於chrome瀏覽器V8引擎、C++語言編寫的,本質上是Js的運行環境;
能夠解析js代碼;
提供系統級別的api:
一、文件的讀寫
二、進程的管理
三、網絡通訊java
安裝:
linux 上安裝nodejs
mac 上安裝node:
升級到mac系統到最新;
下載安裝 xcode 集成開發環境;
xcode-select -p 檢查是否安裝了xcode 若是返回一個路徑,說明已經安裝了;若是沒有安裝
xcode-select --install
安裝python;
安裝homebrew 「是針對Mac下的套件管理器,至關於ubuntu下的apt-get,至關於CentOS下的yum
homebrew 依賴於 ruby,若是安裝不成功,嘗試升級ruby版本;
brew install node mongodb
node -v
安裝 node 版本管理工具 n
npm install -g n
n的使用
n 0.10.22
n
-- 用 nodejs 建立一個服務器;
本質上是一個 javascript 的執行環境,只不過加上封裝、web底層的處理,賦予了更多的能力;
保存爲server.jsnode
1 const http = require('http'); // 加載http模塊,這個模塊是由js編寫的;指責是建立服務器,處理 http 相關任務 2 const hostname = '127.0.0.1'; 3 const port = 3000; 4 const server = http.createServer((req, res) => { 5 // 經過 createServer 建立一個web服務器,有請求從監聽的端口過來時,調用裏邊匿名的回調函數;req用來獲取此次請求相關的信息,res告訴服務器,響應一些內容; 6 res.statusCode = 200; 7 res.setHeader('Content-Type', 'text/plain'); 8 res.end('Hell Frank,fighting ! \n'); 9 }); 10 11 server.listen(port, hostname, () => { // 讓服務器在端口上監聽請求;服務器就 ready 了,就能夠收到任何來自3000端口的請求 12 console.log(`Server running at http://${hostname}:${port}/`); 13 });
node server.js // 執行python
瀏覽器刷新 http://127.0.0.1:3000/ jquery
Nodejs 環境 和 瀏覽器的執行環境的異同:linux
(1)均可以正常的執行 js 代碼
(2)宿主 瀏覽器是 window; node中沒有 window document,有process http 等模塊,可是瀏覽器沒有git
Node.js 的模塊 與 Commonjs規範:github
以前的http 和 process 都是nodejs的模塊;
頁面中有大量js引入時,尤爲是有相互依賴的狀況下,很容易被覆蓋掉,方法被重寫了,js天生缺乏一種模塊管理機制,來隔離實現不一樣功能的js片斷,避免他們相互污染;
爲此咱們常常採用命名空間的方式,把變量和函數限制到某個特定的做用域內,人肉約定一套命名規範來約束代碼,從而保障代碼的安全執行,好比jQuery中,有許多的變量和方法,必須經過$調用;
commonjs 並不像 jquery 是一套具體實現某功能的庫,他是一套規範,包括模塊、包、系統、二進制、單元測試等等,來約定 javascript 怎麼來組織,怎麼編寫,同時大部分標準也是在擬定和討論之中的;
首先把執行不一樣任務的代碼塊看作成一個獨立的模塊,每個模塊看做成一個獨立的做用域,但並非孤立的,可能存在某種依賴關係,對於一個模塊能夠分紅三個部分:模塊的定義、模塊的標示、模塊的引用;js規範。
Nodejs借鑑 commonjs 模塊組織的理念,實現了一套模塊管理系統;web
模塊的分類:
核心模塊、本地模塊、第三方模塊;mongodb
url.parse() 解析url:
url.format()
url.resolve()
querystring 解析參數:
querystring.stringfy({name: 'frank', age: 19}) 將參數對象序列化解析爲參數字符串,默認用=連接key alue,&;
querystring.parse() 將參數對象反序列化;三個參數('', ',' , ':' , 0)
querystring.escape(str) 參數轉譯
querystring.unescape() 參數反轉譯
網絡通訊協議,http客戶端發起請求,建立端口;http服務器在端口監聽客戶端請求;http服務器向客戶端返回狀態信息和內容;
(1)瀏覽器輸入url,接下來發生了什麼。。。
-1-、chrome瀏覽器搜索自身的DNS緩存,看看本身的DNS緩存有沒有 baidu.com 對應的ip地址緩存,或緩存有沒有過時,該緩存有效時間約 1 分鐘;
「chrome://net-internals/#dns 可查看瀏覽器dns緩存」
-2-、如沒有,搜索操做系統自身的DNS緩存;
-3-、如沒有,讀取本地 host 文件,找是否有 DNS 的配置項;
-4-、如沒有,瀏覽器發起一個 DNS 的系統調用,向寬帶運營商發起域名解析請求;
「 寬帶運營商服務器查看自己緩存,看是否有配置項,是否過時,
若是沒有,運營商服務器 代替瀏覽器發起一個迭代DNS解析請求 ---> 萬網等域名服務上返回 ip 地址,
運營商服務器把返回的結果 -> 返回操做系統內核並緩存起來,操做系統內核把結果返回給瀏覽器,瀏覽器拿到了對應的ip地址,域名解析完成。
-5-、瀏覽器得到域名對應的 ip 地址後,發起經典的 HTTP 「三次握手」;「TODO」
「瀏覽器向服務器發起TCP鏈接請求,經過層層路由設備到達服務器端的網卡,而後進入到服務器內核的 TCP/IP 協議棧,通過防火牆的過濾,創建起TCP/IP鏈接;」
-6-、 創建起 TCP/IP 鏈接以後,瀏覽器就能夠向服務器發送 HTTP 請求了,
-7-、 服務器接收請求後,根據路徑參數,通過後端的一些處理以後,把處理的結果返回給瀏覽器,瀏覽器進行渲染出頁面;
(2)請求方法:
GET : 讀取;POST:提交數據; PUT:更新信息;DELETE:刪除;HEAD;TRACE;
(3)狀態碼:
1xx : 請求已經發出,正在處理
2xx : 成功接受 「200 客戶端請求成功」
3xx : 須要重定向 : TODO
4xx : 客戶端錯誤:
400 客戶端語法等錯誤,服務器不能理解
401 請求沒有通過受權」「服務器收到請求,拒絕服務,多是沒有權限等」「請求資源不存在,也多是url錯了」
5xx : 服務器端的錯誤: 「500服務器發生了不可預期的錯誤」「服務器當前不能處理該請求,可能過一段時間會恢復正常」
(4)https 協議
https 是基於 http,在 http 基礎上增長了 SSL/TLS 握手、數據加密傳輸;
專門用於處理加密訪問;
搭建https服務器時須要ssl證書;
建立 https 服務器:
(1)回調:
回調是異步編程最基本的方法,對於nodejs,須要按照順序執行異步邏輯時,採用後續傳遞的方式,將後續邏輯封裝在回調函數中做爲起始函數的參數,逐層嵌套;
(2)同步 異步:
同步就是執行一個任務,後一個任務等待前一個任務完成後開始執行,程序的執行順序與任務的排列順序有關;
js中經典的異步: setTimeout setInterval
(3)I/O 磁盤的讀入 輸出:
(4)單線程 / 多線程:
(5)阻塞 / 非阻塞:
(6)事件: 瀏覽器中鼠標的點擊,拖拽窗口,
(7)事件驅動:
(8)基於事件驅動的回調:
(9)事件循環: eventloop 是個回調函數隊列,單線程,先進先出
- 做用域:和調用函數、訪問變量的能力有關;局部做用域能夠訪問全局做用域的變量和函數,全局的訪問不到局部的;
- 上下文: this 關鍵字有關,是調用當前可執行代碼的引用;
「上下文表明 this 變量的值和指向,決定一個函數被怎麼調用,當一個函數被做爲一個對象的方法調用的時候,this老是指向調用這個方法的對象; 」
「JS中,this 表示當前函數的擁有者,一般把擁有者叫做「執行上下文」;
this 是 js 的關鍵字,是函數運行時自動生成的內部對象;只能在函數內部使用;
對於函數的上下文執行對象,須要依據當前的運行環境而定,在全局運行的上下文中,this指向全局對象,在函數內部,this取決於函數被調用的方式:以下
「 this指向pat對象;」
「 全局調用,this指向全局對象,瀏覽器:window;node環境指向 global 」
「 構造函數中使用this,this指向新購建好的對象,實例對象;」
JS的函數存在概念:定義時的上下文,運行時的上下文,上下文是能夠改變的。函數的方法 call() apply() 能夠改變上下文執行對象,能夠在自定義上下文中執行函數
「 運行時改變上下文:經過call 改變this上下文,在調用時,將 this 指向dog,實現繼承;」
「 定義時改變上下文:這種方法不是執行是改變this指向,定義時已經改變了指向;」
node 事件沒有冒泡、捕獲等;
var EventEmitter = require('events').EventEmitter
var life = new EventEmitter() life.setMaxListeners(11) // 默認監聽不超過10個,不然報 warning life.on('eventname', function (who) { // 此時 on 能夠用 addEventListener 替換 console.log('給' + who+ '倒水') }) lief.emit('eventname', '漢子')
lief.emit('eventname', '漢子') 返回一個布爾值,true,說明事件被監聽過;
Promise
異步的解決方案:
(1)回調
(2)事件機制
(3)對事件增長事件監聽,對某個異步操做增長異步觸發,
(4)訂閱者發佈者 的 觀察者模式
(5)promise
Promise A 與 Promise A+規範:
promise庫:bluebird
promise重構網站爬蟲:「待續」
Nodejs 中的網絡模塊 - NET:
互聯網的價值基礎是數據傳送,一塊兒都圍繞數據展開,好比發送、接受等,但這一切都離不開網絡;http、https都是創建在 NET 模塊之上的;
Buffer :緩衝,在Nodejs中處理二進制的數據,Buffer的存在是由於,javascript的字符串是以 utf-8 編碼格式存儲的,處理二進制的能力是很弱的,而網絡層對於資源的存儲請求等都是以二進制的格式交互的,因此 Nodejs 就有 Buffer 這個接口,來建立專門存放二進制數據的緩存區,而且提供給了一些方法對於這些數據進行進一步的處理;
Buffer 在 Nodejs 中是能夠直接訪問的,不須要 require 來加載,Buffer 有一些靜態方法,能夠實例化,實例化以後的對象上有相應的屬性和方法;
生成實例的方法(1)new (2)傳入一個size,以字節數爲單位,傳遞給構造函數,生成一段內存區間; (3)經過數組初始化;
(1)經過new實例化
Buffer 是個對象,也是一個構造函數,具備本身的屬性和靜態方法;
經過它new出來的實例,實際上是V8引擎分配的一段內存;基本上是數組,成員都是整數值;
Buffer對象與字符串相互轉換過程是須要指定編碼格式的,默認是 utf-8;
(2)傳入一個size,以字節數爲單位,傳遞給構造函數,生成一段內存區間
length屬性表示緩存區的大小,寫入內容超出長度的部分是不會被緩衝的,以下:
(3)經過數組實例化,實例化後能夠經過下標來訪問某一個值;數組的一個某一項若是爲小數,訪問到的也只是整數
- Buffer 實例的方法 -
- stream 流-
事件驅動,可控制;
Readable 可讀流 -- > 讀取外部的數據,並吧讀到的數據緩存到內部的 Buffer 數組中;
Writable 可寫流 -- > 負責消費數據,從可讀流中獲取數據,從獲取到的 trunk 數據塊進行處理;
Duplex --
Transform -- 轉換流
eg:
定製可讀流、定製可寫流、定製轉換流,而且實現他們的內置接口;