1、node.js介紹
誕生於2009年,它不是一門語言也不是一門框架,它是基於Google V8引擎的JavaScript運行時環境,同時結合Libuv拓展了JavaScript功能,使之支持IO,fs等語言纔有的特性,使得JavaScript能夠同時具有DOM操作(瀏覽器)和I/O,文件讀寫、操作數據庫等能力。
應用:淘寶雙十一、去哪兒網PC端核心業務;前端工具 VScode、webpack等具有Node.js開發
node的包管理工具npm成爲世界中開源包管理中最大的生態、功能強大。
2、特點
- 事件驅動
- 非阻塞IO模型(異步)
- 輕量和高效
3.、在一線企業中的應用
①作爲中間層
②做一些小型網站的後端
- 減少客戶端內存,不會像MVVM模式的項目把頁面渲染和數據請求都壓在客戶端,而是在服務端完成
- SEO性好,不像mvvm模式頁面由js生成,而是在服務端渲染好html字符,有利於網頁被搜索到
- 前端可以操控的範圍增多,甚至可以操作服務器,數據層面的優化,比如中間層使用nginx、redis來優化項目,應對高併發。
優點:中間層模式是一種開發模式上的進步,但這種好的模式成本過高,如果沒有一定量級的項目沒必要使用
4、node.js中的module.exports和exports
- Node中每個模塊都有一個module對象,module對象中有一個exports屬性作爲藉口對象,我們需要把模塊之間公共方法或屬性掛載到這個接口對象中,方便其他的模塊使用 這些公共的方法或屬性。
- Node中每個模塊的最後,都會return module.exports, 默認module.exports = {}
- Node中每個模塊都會把module.exports指向的對象賦值給一個變量exports,即module.exports == exports
- module.exports == XX,表示當前模塊導出一個單一成員,require導入的就是一個{ ... }
- 如果需要導出多個成員,必須使用module.exports.xxx = xxx。
5、node、js中require加載第三方包的規則
- 找寫require文件同級目錄中的node_module下面的同名文件,同級目錄中沒有node_module,就找父級(父級、祖父級等)的node_module
- 找該文件夾下面package.json中的main,這個main屬性值就是你引入的文件路徑
6、npm 常見命令
npm 全名爲node package manager,我們平時開發項目都需要使用npm命令安裝依賴
7、文件讀取(同步讀取)
- 使用fs.readFileSync()讀取文件,第一個參數爲文件名或文件描述符,第二個參數是一個對象,該對象有兩個屬性,一個是encoding,一個是flag(是讀取文件--“r”,還是文件寫入--“w”,還是追加--“a”)。官方文檔該方法描述如下:
- 讀取文件寫法如下
const fs = require("fs");
const content = fs.readFileSync("txt.txt", {flag: 'r'});
console.log(content.toString());
或者(指定encoding的編碼格式需要與讀取文件的編碼格式一致,因爲此例中的txt.txt文件格式是utf-8,所以我們指定utf-8之後可直接輸出)
const fs = require("fs");
const content = fs.readFileSync("txt.txt", {flag: 'r', encoding: "utf-8"});
console.log(content);
- 輸出的結果如下
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
這是一個txt.txt
總結:readFileSync讀取文件中如果不設置encoding編碼方式,直接輸出是一耳光Buffer緩衝區,需要使用toString轉換成字符串進行展示或者是操作;如果在readFileSync中設置encoding編碼方式,使不使用toString都會輸出字符串。
8、文件讀取(異步讀取)
- 使用fs.readFile()讀取文件,第一個參數爲文件名或文件描述符(必傳);第二個參數是一個對象(可傳可不傳)該對象有兩個屬性,一個是encoding,一個是flag(是讀取文件--“r”,還是文件寫入--“w”,還是追加--“a”),如果不傳,默認encoding爲“utf-8”,默認flag爲“r”,;第三個參數callback(必傳),官方文檔該方法描述如下:
- 該方法讀取如下:
const fs = require("fs");
fs.readFile('txt.txt', (err, data) => {
if(err) {
console.log(err);
} else {
console.log(data);
}
console.log("我證明javascript是單行執行!")
});
console.log("我證明他是異步!");
- 輸出結果爲
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
我證明他是異步!
<Buffer e8 bf 99 e6 98 af e4 b8 80 e4 b8 aa 74 78 74 2e 74 78 74 20 20>
我證明javascript是單行執行!
總結:如果不指定編碼方式默認輸出爲Buffer緩衝器,readFile是異步函數,javascript是單行執行。
- 要輸出utf-8格式的文本需要指定encoding爲utf-8
const fs = require("fs");
fs.readFile('txt.txt', {encoding: "utf-8"}, (err, data) => {
if(err) {
console.log(err);
} else {
console.log(data);
}
console.log("我證明javascript是單行執行!")
});
console.log("我證明他是異步!");
- 輸出結果爲正常的字符串
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
我證明他是異步!
這是一個txt.txt
我證明javascript是單行執行!
- 封裝異步讀取文件Promise
function readFileAsync(url) {
return new Promise( (resolve, rejects) => {
fs.readFile(url, {encoding: 'utf-8', flag: 'r'}, (err, data) => {
if(!err){
resolve(data);
} else {
rejects(err)
}
})
})
}
readFileAsync("txt.txt").then( res => {
console.log(res);
})
9、文件寫入(跟文件讀取一樣,分異步和同步方法,因同步一般不會使用,下面只介紹異步方法)
-
writeFile文件寫入,第一個參數是文件名稱(必填),第二個參數爲寫入的數據(必填),第三個參數是編碼方式和操作類型(flag :append --> a 追加 ;write --> w 文件寫入),該參數是可選填,第四個參數是錯誤回調函數,官方此方法介紹如下圖:
- 實例操作:封裝一個寫入文件(追加方式)的promise函數(使用async 和 await)
const fs = require("fs");
const { resolve } = require("path");
const { rejects } = require("assert");
function writefs(url, data, flag = "a") {
return new Promise((resolve, rejects) => {
fs.writeFile(url, data, {encoding: "utf-8", flag}, err => {
if(!err){
resolve("寫入成功!");
} else {
rejects(err);
}
})
})
}
async function writeFileAsync() {
let connect = await writefs("txt.txt", "喫餃子\n");
console.log(connect);
let connect1 = await writefs("txt.txt", "紅燒獅子頭\n");
console.log(connect1);
let connect2 = await writefs("txt.txt", "水餃\n");
console.log(connect2);
}
writeFileAsync()
- 輸出
PS C:\Users\tcsc6\Desktop\node_1> node .\index.js
寫入成功!
寫入成功!
寫入成功!
10、刪除文件,同樣只介紹異步刪除文件 fs.unlink(path, callback)
- 使用fs.unlink(path,callback),第一個參數是文件路徑,第二個參數是回調函數(只有err)
- 代碼實例
const fs = require("fs");
fs.unlink("txt222.txt", () => {
console.log("刪除成功!");
})
- 執行結果:
11、Buffer緩衝器(安全的alloc)
- 解決的問題
- 數組不能進行二進制數據的操作
- 因爲js數組一般不指定長度,數組地址存放在heap中,存放的地方也不連續,引用的時候效率就會降低,導致js數組不想Java、python等語言效率高
- buffer內存空間開闢出固定大小的內存,存放的是連續的引用的時候很容易找到,效率高
- 官網方法
- 實例及輸出
const buf = Buffer.alloc(10);
buf[0] = "123";
buf[1] = "255";
console.log(buf);
console.log(buf.toString());
console.log(buf[0]);
console.log(buf[0].toString());
總結:Buffer.alloc(10)開闢10個字節的數組,數組的每一項都可以進行賦值,之後我們可以通過獲取數組項的方法獲取某一項;
12、同樣的還有allocUnsafe,不安全Buffer緩衝器
- 官網方法介紹
- 實例
const unsafebuf = Buffer.allocUnsafe(10);
unsafebuf[0] = "123";
console.log(unsafebuf);
console.log(unsafebuf[0].toString() + "\n");
總結:Buffer.allocUnsafe()同樣也可以通過傳入數字進行給Buffer設置長度,獲取的時候使用[0、、]方式獲取。
13、讀取文件目錄(fs.readdir() )這裏只介紹異步