node.js 史上最詳細 (博主持續更新)

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)

  • 解決的問題
  1. 數組不能進行二進制數據的操作
  2. 因爲js數組一般不指定長度,數組地址存放在heap中,存放的地方也不連續,引用的時候效率就會降低,導致js數組不想Java、python等語言效率高
  3. 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() )這裏只介紹異步

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章