http模塊:配置簡單 的web服務,npm/cnpm工具javascript
express框架:express中間件進行服務配置;路由;請求處理;html
DB服務:學習使用mysql關係型數據庫;java
web接口服務:使用express、koa簡單配置接口服務、JSON解析;node
nodejs RESTful API:提供跨語言、跨平臺的服務接口、支持web/appmysql
node文件系統:服務端基本的文件讀寫操做nginx
Node.js是一個讓JavaScript運行在服務器端的開發平臺,它讓JavaScript的觸角伸到了服務器端。但Node.js彷佛與其它服務器端語言有點不一樣:web
Node.js不是一種獨立的語言,與PHP、Python等「既是語言,又是平臺」不一樣,Node.js使用的是JavaScript進行編程,Node.js是一個工具,語言還是JavaScript。sql
與PHP、JSP等相比,Node.js跳過了apache、tomcat、nginx、iis等http服務器,它本身不用創建在任何服務器軟件之上。數據庫
Node.js哲學:花最小的硬件成本,追求更高的併發,更高的處理性能。express
Node採用一系列「非阻塞」庫來支持事件循環的方式。本質上就是爲文件系統、數據庫之類的資源提供接口。向文件系統發送一個請求時,無需等待硬盤(尋址並檢索文件),硬盤準備好的時候非阻塞接口會通知Node。該模型以可擴展的方式簡化了對慢資源的訪問, 直觀,易懂。尤爲是對於熟悉onmouseover、onclick等DOM事件的用戶,更有一種似曾相識的感受。
單線程:
說明Node.js是單線程的一個實例 :
Node.js能夠在不新增額外線程的狀況下,依然能夠對任務進行併發處理 —— Node.js是單線程的。它經過事件循環(event loop)來實現併發操做,對此,咱們應該要充分利用這一點 —— 儘量的避免阻塞操做,取而代之,多使用非阻塞操做。
事件驅動:
異步回調:至關於一個服務員照顧多個顧客
說明實例:當有多個用戶同時訪問的時候,會出現同一個用戶進來和讀取完畢不連續的狀況
只要I/O越多,Node.js宏觀上越並行;但運算越多,Node.js宏觀上越不併行,此時網頁打開速度嚴重變慢,由於計算過程當中CPU只能爲某一用戶服務,難以脫身,因此Node.js線程就被這一用戶霸佔了。
所以Node.js適合開發I/O多的業務,而不適合計算任務繁重的業務。
非阻塞I/O:
例如:當訪問數據庫取得數據的時候,須要一段較長的時間,在傳統的處理機制中,在執行了訪問數據庫代碼以後,整個線程都將暫停下來等待數據庫返回結果才能執行後面的代碼,也就是說I/O阻塞了後面代碼的執行,極大的下降了程序的執行效率。
因爲Node.js採用了非阻塞I/O機制,所以在執行了訪問數據庫的代碼以後,將當即轉而執行其後面的代碼,將數據庫返回結果的處理代碼放在回調函數中,從而提升了程序的執行效率。
當某個I/O執行完畢時,將以事件的形式通知執行I/O操做的線程,線程執行這個事件的回調函數。爲了處理異步I/O,線程必須有事件循環,不斷的檢查有沒有未處理的事件,依次予以處理。
在阻塞模式下,一個線程只能處理一項任務,要想提升吞吐量必須經過多線程。而非阻塞模式下,一個線程永遠在執行計算操做,這個線程的核心利用率永遠是100%,因此這個是一個特別有哲理的解決方案:與其人多,但好多人閒着,還不如一我的玩命,往死裏幹活。
Node..js適合開發的業務:
當業務程序須要處理大量併發的I/O,而在向客戶端發出響應以前,應用程序內部並不須要進行很是複雜的處理的時候,Node..js很是合適。Node..js也很是適合和websocket配合,開發長鏈接的實時交互應用程序,好比:用戶表單收集、考試系統、聊天室、圖文直播、提供JSON的API(爲MVVM框架使用)。
一、經常使用的命令:
dir:列出當前文件夾下的全部文件;
cd 目錄名:進入到指定的目錄;
md 目錄名:建立一個指定的文件夾;
rd 目錄名:刪除一個指定的文件夾;
二、目錄:
.:表示當前目錄;
..:表示上一級目錄;
三、環境變量:
path:當咱們在命令行窗口打開一個文件或調用一個程序時系統會首先在當前目錄下尋找程序,若是找到了則直接打開,若是沒有找到則會依次到環境變量path的路徑中尋找,直到找到爲止,若是沒有找到則會報錯。
四、快速進入指定文件夾的方法:
在指定文件夾的地址欄中輸入:cmd
進程:負責爲程序的運行提供必備的環境,至關於工廠中的車間;
線程:計算機中最小的計算單元,負責執行進程中的程序,至關於工廠中的工人。
cmd中進入hello.js所在文件夾,cmd中輸入:
WebStorm菜單的File->Settings:搜索node,找到Node.js and NPM,在右側的Node interpreter中輸入node.exe所在位置便可。
WebStorm菜單的File->Settings:搜索node,找到Node.js and NPM,在右側的Coding Assistance中啓用便可。
在Node中,一個js文件就是一個模塊;
在 Node中,每個js文件的js代碼都是獨立運行在一個函數中,好比:
實際上是:
而不是全局做用域,因此一個模塊中的變量和函數在其它模塊中沒法訪問 。
在Node中,經過require()函數來引入外部模塊,require()中能夠傳遞一個文件的路徑做爲參數,node將會自動根據該路徑來引入外部模塊,這裏路徑若是使用相對路徑,則必須以「.」或者「..」開頭;
咱們能夠經過exports來向外部暴露變量或者方法,只須要將須要暴露給外部的變量或者方法設置爲exprots的屬性便可。
使用require()引入模塊之後,該函數會返回一個對象,這個對象表明的是引入的模塊。
咱們使用require()引入外部模塊時,使用的就是模塊標識。
模塊分紅兩大類:
核心模塊:由node引擎提供的模塊,核心模塊的標識就是模塊的名字;
文件模塊:用戶自定義的模塊,文件模塊的標識就是文件的路徑。
node模塊中用var定義的變量都是局部變量,取消掉var時定義的變量纔是所有變量:
輸出:
由此可知:
當node在執行模塊中的代碼時,它首先會在代碼的最頂部添加以下代碼:
在代碼的最底部,添加以下代碼:
實際上,模塊中的代碼都是包裝在一個函數中執行的,而且在函數執行時,同時傳遞了5個實參:
exports:該對象用來將對象或者函數暴露到外部,
require:函數,用來引入外部的模塊,
module:用來表明的是當前模塊自己,exports就是模塊的屬性。既能夠用exports導出,也能夠用module.exports導出二者指向的是同一個對象,
__filename:當前模塊的完整路徑,
__dirname:當前模塊所在文件夾的完整路徑
本質上二者是相等的,可是exports只能經過「.」的方式向外暴露內部變量,而modules.exports既能夠經過「.」的形式,也能夠直接賦值;
CommonJS的包規範容許咱們將相關的模塊組合在一塊兒,造成一組完整的工具。
CommonJS的包規範包括包結構和包描述文件。
包結構:
package.json:必須
bin:可執行的二進制文件,非必須
lib:js文件,非必須;
doc:文檔,非必須;
test:單元測試,非必須
包描述文件:
用於表達非代碼相關的信息,它是一個json文件-package.json,位於包的根目錄下,是包的重要組成部分。
至關於360安全衛士裏的軟件管家。
對於node而言,npm幫助其完成了第三方模塊的發佈、安裝和依賴等。藉助npm,node與第三方模塊之間造成了很好的一個生態系統。
npm -v:查看npm版本;
npm version: 查看全部模塊的版本;
npm search 包名:搜索包;
npm install/i 包名 :安裝包;
npm remove/r 包名:刪除包;
npm remove/r 包名 --save:將包名在依賴中刪除(node _modules中不刪除);
npm install 包名 --save:安裝包並添加到依賴中(package.json的dependencies中);
npm install:下載當前項目所依賴的包(package.json的dependencies中的包);
npm install 包名 -g:全局安裝包(全局安裝的包通常是一些工具)
經過npm下載的包都放到node_modules中,咱們經過npm下載的包直接經過包名引用便可。
node在經過模塊名字來引用模塊時它會首先在當前目錄的node_modules中尋找是否含有該模塊,若是有則直接使用,若是沒有則直接去上一級目錄的node_modules中尋找,若是有則直接使用,若是沒有,則繼續再去上一級目錄中尋找,直到找到磁盤的根目錄,若是依然沒有,則直接報錯。
Node.js 全部的異步 I/O 操做在完成時都會發送一個事件到事件隊列。
Node.js 裏面的許多對象都會分發事件:一個 net.Server 對象會在每次有新鏈接時觸發一個事件, 一個 fs.readStream 對象會在文件被打開的時候觸發一個事件。 全部這些產生事件的對象都是 events.EventEmitter 的實例。
events 模塊只提供了一個對象: events.EventEmitter。EventEmitter 的核心就是事件觸發與事件監聽器功能的封裝。
你能夠經過require("events");來訪問該模塊。
EventEmitter 對象若是在實例化時發生錯誤,會觸發 error 事件。當添加新的監聽器時,newListener 事件會觸發,當監聽器被移除時,removeListener 事件被觸發。
下面咱們用一個簡單的例子說明 EventEmitter 的用法:
執行結果以下:
運行這段代碼,1 秒後控制檯輸出了 'some_event 事件觸發'。其原理是 event 對象註冊了事件 some_event 的一個監聽器,而後咱們經過 setTimeout 在 1000 毫秒之後向 event 對象發送事件 some_event,此時會調用some_event 的監聽器。
EventEmitter 的每一個事件由一個事件名和若干個參數組成,事件名是一個字符串,一般表達必定的語義。對於每一個事件,EventEmitter 支持 若干個事件監聽器。
當事件觸發時,註冊到這個事件的事件監聽器被依次調用,事件參數做爲回調函數參數傳遞。
讓咱們如下面的例子解釋這個過程:
執行以上代碼,運行的結果以下:
以上例子中,emitter 爲事件 someEvent 註冊了兩個事件監聽器,而後觸發了 someEvent 事件。
運行結果中能夠看到兩個事件監聽器回調函數被前後調用。 這就是EventEmitter最簡單的用法。
EventEmitter 提供了多個屬性,如 on 和 emit。on 函數用於綁定事件函數,emit 屬性用於觸發一個事件。接下來咱們來具體看下 EventEmitter 的屬性介紹。
方法
序號 | 方法 & 描述 |
---|---|
1 | addListener(event, listener) 爲指定事件添加一個監聽器到監聽器數組的尾部。 |
2 | on(event, listener) 爲指定事件註冊一個監聽器,接受一個字符串 event 和一個回調函數。 server.on('connection', function (stream) { |
3 | once(event, listener) 爲指定事件註冊一個單次監聽器,即 監聽器最多隻會觸發一次,觸發後馬上解除該監聽器。 server.once('connection', function (stream) { |
4 | removeListener(event, listener) 移除指定事件的某個監聽器,監聽器必須是該事件已經註冊過的監聽器。 它接受兩個參數,第一個是事件名稱,第二個是回調函數名稱。 var callback = function(stream) { |
5 | removeAllListeners([event]) 移除全部事件的全部監聽器, 若是指定事件,則移除指定事件的全部監聽器。 |
6 | setMaxListeners(n) 默認狀況下, EventEmitters 若是你添加的監聽器超過 10 個就會輸出警告信息。 setMaxListeners 函數用於提升監聽器的默認限制的數量。 |
7 | listeners(event) 返回指定事件的監聽器數組。 |
8 | emit(event, [arg1], [arg2], [...]) 按參數的順序執行每一個監聽器,若是事件有註冊監聽返回 true,不然返回 false。 |
類方法
序號 | 方法 & 描述 |
---|---|
1 | listenerCount(emitter, event) 返回指定事件的監聽器數量。 |
events.EventEmitter.listenerCount(emitter, eventName) //已廢棄,不推薦
events.emitter.listenerCount(eventName) //推薦
事件
序號 | 事件 & 描述 |
---|---|
1 | newListener
該事件在添加新監聽器時被觸發。 |
2 | removeListener
從指定監聽器數組中刪除一個監聽器。須要注意的是,此操做將會改變處於被刪監聽器以後的那些監聽器的索引。 |
實例
如下實例經過 connection(鏈接)事件演示了 EventEmitter 類的應用。
建立 main.js 文件,代碼以下:
以上代碼,執行結果以下所示:
server.js
handler.js
index.html
Buffer的結構和數組很像,操做的方法也和數組相似;
數組中不能存儲二進制的文件,而Buffer就是專門用來存儲二進制數據;
爲何要用Buffer?Node.js其實就作兩件事,一是接收請求,另外一個是發送請求,請求都是以二進制的方式傳遞的,接收之後或者發送以前二進制數據都是放在緩存中。
使用Buffer不須要引用模塊,直接使用便可;
在Buffer中存儲的是二進制數據,但在顯示時是以十六進制的形式顯示;存入時的數字能夠是任何進制,但在控制檯或者頁面就是必定只能以十進制輸出顯示,若是存儲的是字符的話能夠用其它進制顯示,方式str.toString(x);
Buffer中每個元素的範圍是00-ff(16進制) <=> 0-255(10進制) <=> 00000000-11111111(2進制);
計算機中1個0或者1個1咱們稱之爲1位(bit),計算機中數據是以字節爲單位傳輸的;
8bit=1byte(1字節);
1024byte=1kb;
1024kb=1mb;
1024mb=1gb;
1024gb=1tb;
Buffer中的1個元素佔用內存的1個字節;
Buffer的大小一旦肯定,則不能修改,Buffer其實是對底層內存的直接操做;
server.js
review.html
404.html
重構路由代碼:
app.js
server.js
router.js
handler.js
文件系統簡單來講就是經過Node.js來操做系統中的文件;
使用文件系統首先須要引入fs模塊,fs是核心模塊,直接引入不須要下載;
文件的寫入步驟:
手動步驟:
a、打開文件;
b、向文件中寫入內容;
c、保存並關閉文件;
一、同步寫入文件:
二、異步寫入文件:
三、簡單文件寫入(不須要打開文件):
Flag | 描述 |
---|---|
r | 以讀取模式打開文件。若是文件不存在拋出異常。 |
r+ | 以讀寫模式打開文件。若是文件不存在拋出異常。 |
rs | 以同步的方式讀取文件。 |
rs+ | 以同步的方式讀取和寫入文件。 |
w | 以寫入模式打開文件,若是文件不存在則建立。 |
wx | 相似 'w',可是若是文件路徑存在,則文件寫入失敗。 |
w+ | 以讀寫模式打開文件,若是文件不存在則建立。 |
wx+ | 相似 'w+', 可是若是文件路徑存在,則文件讀寫失敗。 |
a | 以追加模式打開文件,若是文件不存在則建立。 |
ax | 相似 'a', 可是若是文件路徑存在,則文件追加失敗。 |
a+ | 以讀取追加模式打開文件,若是文件不存在則建立。 |
ax+ | 相似 'a+', 可是若是文件路徑存在,則文件讀取追加失敗。 |
四、使用絕對路徑寫入文件:
五、流式文件寫入:
同步、異步、簡單文件的寫入都不太適合大文件的寫入,性能較差,容易致使內存溢出。
五、簡單文件讀取:
六、流式文件讀取:
七、fs其它操做:
• 驗證路徑是否存在
– fs.existsSync(path)
• 獲取文件信息
– fs.stat(path, callback)
– fs.statSync(path)
• 刪除文件
– fs.unlink(path, callback)
– fs.unlinkSync(path)
列出文件
– fs.readdir(path[, options], callback)
– fs.readdirSync(path[, options])
• 截斷文件
– fs.truncate(path, len, callback)
– fs.truncateSync(path, len)
• 創建目錄
– fs.mkdir(path[, mode], callback)
– fs.mkdirSync(path[, mode])
刪除目錄
– fs.rmdir(path, callback)
– fs.rmdirSync(path)
• 重命名文件和目錄
– fs.rename(oldPath, newPath, callback)
– fs.renameSync(oldPath, newPath)
• 監視文件更改寫入
– fs.watchFile(filename[, options], listener)
響應 json:
響應HTML頁面 :
main.js:
index.html:
一、什麼是express?
express是也一個基於node.js的極簡、靈活的web開發框架。能夠實現很是強大的web服務器功能。
二、express的特色:
能夠設置中間件響應或過濾http請求;
可使用路由實現動態網頁,響應不一樣的http請求;
內置支持ejs模板(默認是jade模板)實現模板渲染生成html;
三、express-generator生成器:
express-generator是express官方團隊爲開發者準備的一個快速生成工具,能夠很是快速的生成一個基本的express開發框架。
四、express安裝與使用:
1)安裝express-generator生成器;
安裝完成後可使用express命令。
2)建立項目:
3)安裝依賴:
4)開啓項目
5)測試項目:
打開瀏覽器輸入localhost
安裝驅動:
注意:cnpm install mysql是安裝nodejs的mysql模塊而不是安裝mysql數據庫,你的應用經過這個驅動程序鏈接並操做mysql中的庫和表。
若是你的電腦中沒有mysql,則請先安裝,相關教程以下:
https://jingyan.baidu.com/article/363872ec2e27076e4ba16fc3.html
在進行數據庫操做前,你須要將如下SQL 文件導入到你的 MySQL 數據庫中。
查詢數據
將上面咱們提供的 SQL 文件導入數據庫後,執行如下代碼便可查詢出數據:
插入數據
更新數據
刪除數據
nodemon: