操作fs模塊
const path = require("path");
const fs = require("fs");
/*
相對路徑是命令視窗執行的目錄
node 提供了path模塊來操作路徑相關的api, 其中__dirname是一個內置的變數,回傳當前檔案所在的目錄
*/
const getDirUrl = dir => {
return path.resolve(__dirname, dir);
};
for (let i = 0; i < 5; i++) {
fs.writeFileSync(getDirUrl("./create01.text"), i + "、我是測驗資料" + i + "\n", {
flag: "a+",
encoding: "utf-8"
});
}
console.log("hello nodejs");
const data = https://www.cnblogs.com/longbensong/archive/2023/05/16/fs.readFileSync(getDirUrl("./create01.text"), {encoding: 'utf-8'}).toString()
console.log('同步讀取')
console.log(data)
console.log('異步讀取')
fs.readFile(getDirUrl("./create01.text"), (err, data) => {
if(!err) {
console.log(data.toString());
} else {
console.error(err);
}
});
在視窗執行對應的目錄即可,我這里是:

操作http模塊
// 1. 匯入http模塊
const http = require("http");
const fs = require("fs");
const path = require("path");
const mimes = {
html: "text/html",
css: "text/css",
js: "text/javascript",
png: "image/png",
jpg: "image/jpeg",
gif: "image/gif",
mp4: "video/mp4",
mp3: "audio/mpeg",
json: "application/json"
};
//2. 創建服務物件 create 創建 server 服務
// request 意為請求. 是對請求報文的封裝物件, 通過 request 物件可以獲得請求報文的資料
// response 意為回應. 是對回應報文的封裝物件, 通過 response 物件可以設定回應報文
const server = http.createServer((req, res) => {
let { url, method } = req;
// 檔案夾路徑
const rootDir = __dirname + "/public";
let filePath = rootDir + url;
if (!fs.existsSync(filePath)) {
return
}
// 讀取內容
fs.readFile(filePath, (err, data) => {
if (err) {
console.log(err);
//設定字符集
res.setHeader('content-type','text/html;charset=utf-8');
//判斷錯誤的代號
switch(err.code){
case 'ENOENT':
res.statusCode = 404;
res.end('<h1>404 Not Found</h1>');
case 'EPERM':
res.statusCode = 403;
res.end('<h1>403 Forbidden</h1>');
default:
res.statusCode = 500;
res.end('<h1>500 Internal Server Error</h1>');
}
return;
}
//獲取檔案的后綴名
let ext = path.extname(filePath).slice(1);
//獲取對應的型別
let type = mimes[ext];
if(type){
if(ext === 'html'){
res.setHeader('content-type', type + ';charset=utf-8');
}else{
res.setHeader('content-type', type);
}
}else{
//沒有匹配到-默認設定二進制檔案型別
res.setHeader('content-type', 'application/octet-stream');
}
//回應檔案內容
res.end(data);
});
});
//3. 監聽埠, 啟動服務
server.listen(9000, () => {
console.log("服務已經啟動,9000埠監聽中...");
});
如上最簡單的http 服務起來了,在瀏覽器中 輸入 http://localhost:9000/index.html 得到如下頁面

通過匹配后綴,在public檔案中回傳對應的資源,代碼結構如下

都是一些很簡單的代碼就不貼了,如果需要留下郵箱即可,
其他模塊看看官網的檔案即可,不在記錄,
框架
上面都是通過原始的方式來使用node,其實node的生態也很豐富,有很多的框架讓我們選擇,如 express、koa2、nestjs、midwayjs 等等
express 基本使用
// 1.0 匯入express
const express = require('express')
// 2.0 express 實體
const app = express()
const port = 9000
// 3.0 路由
app.get('/', (req, res) => {
res.send('基本使用 Hello World!')
})
// 啟動服務
app.listen(port, () => {
console.log(`啟動服務,埠: ${port}`)
})
通常我們使用腳手架,這樣可以得到統一的專案結構 如 express_ generator,具體查看express 官網
中間件-洋蔥模型
??目前比較流行的 nodejs http 服務框架使用攔截器模式,這種模式將 http 請求回應的程序分為若干切面,每個切面上進行一項或若干項關聯的操作,比如說,我們可以通過不同的攔截切面處理用戶資訊驗證、會話(session)驗證、表單資料驗證、query 決議,或者業務邏輯處理等等,這種架構設計讓切面與切面之間彼此獨立,
有點面向切面編程的概念,不知道對不對,
手動實作一個攔截器:實作類似如下效果
async (ctx, next) => {
do sth...
}
通過呼叫next 執行下一個函式,可以中途return退出,也可以繼續呼叫next直到最后一個函式,然后在一層一層的回傳,洋蔥的結構跟這個類似,所以叫洋蔥模型,
這里的中間件其實是一個函式,在外層使用use 注入進來,

next 陳述句后面的代碼,然后繼續上一個中間件的next后置陳述句,繼續重復上述邏輯,直至執行第一個中間件的next后置陳述句,最后輸出,這個執行的機制,稱為洋蔥模型,
模擬洋蔥模型
?洋蔥模型關鍵在于怎么處理next 引數,next是下一個函式的參考, ,可以通過我們索引加閉包,或者累加器的形式來處理,為了方便直接使用累加器的形式即可,如下代碼:
/*
這個思路通過利用累加器函式的特性,回傳一個函式
*/
class Interceptor {
aspects = [];
use (fn) {
this.aspects.push(fn)
return this
}
async run (context) {
// 從右往左開始遍歷
const proc = this.aspects.reduceRight(
function (a, b) {
let flag = false
return async () => {
// a 上一個fn,也就是呼叫的時傳入的 next
if (flag) {
return
}
flag = true
await b(context, a)
}
},() => Promise.resolve())
try {
// 通過這個reduceRight 讓函式串起來了
await proc()
} catch (e) {
console.error(e);
}
}
}
// 測驗
const inter = new Interceptor()
inter.use(function a(context, next) {
console.log("a");
next();
console.log("a_after");
});
inter.use(function b(context, next) {
console.log("b");
next();
console.log("b_after");
});
inter.use(function c(context, next) {
console.log("c");
next();
console.log("c_after");
});
inter.use(function d(context, next) {
console.log("d");
next();
console.log("d_after");
});
inter.run();
輸出a、b、c、d、d_after、c_after、b_after、a_after 其中koa2 原始碼中使用了索引加閉包的形式來處理 原始碼

小結
??理解了nodejs 寫起來還是挺順手的,官網檔案也還好,至于其他如sql、路由、保持會話狀態等后臺基本知識點,看看相關檔案即可,并沒有什么難度,
??nodejs 入門基本也結束了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/552562.html
標籤:其他
上一篇:JS中的偏函式
下一篇:返回列表
