我認爲我已經非常瞭解Node了,我已經使用它寫網站長達三年之久。但是我從來沒有真正的靜下心來閱讀它的官方文檔。
就像長期讀者所知道的,我喜歡在旅行中寫出接口,原型,方法,函數,數據類型還有一些和網站開發相關的,因此我可以填補我不知道的空白,Node文檔是我的最後的文檔,
xxx,所以我想在這篇小文章中分享給大家。我會以降序的方式提出來。就像我遇到新人時我如何穿衣服一樣。
querystring模塊作爲通用的解析器
你可能從一些奇怪的人的數據庫中得到了一些數據,在表單中這些數據是以一系列鍵值對的數組出現的name:Sophie;shape:fox;condition:new.
通常你會像對待javascript對象一樣去處理他們,所以你先創建了一個空對象,然後你創建了一個用;
分段開的數組, 循環遍歷它對於每個值,用:
分離開,然後把數組的第一個值作爲對象的鍵,第二個作爲值。
Right?
NO!!你可以使用querystring
const weirdoString = `name:Sophie;shape:fox;condition:new`;
const result = querystring.parse(weirdoString, `;`, `:`);
// result:
// {
// name: `Sophie`,
// shape: `fox`,
// condition: `new`,
// };
QuaryString Node.js v7.0.0文檔
V8檢查
執行node時用--inspect
,他會告訴你一個URL,把URL粘貼到Chorm中,在開發者工具裏面調試Node,愉快的一天。這裏是Paul Irush這麼做的
這仍然是”實驗性的”,但是就像我的藥物治療一樣,並且我現在做的很好。
nextTick和setImmediate之間的區別
如果你能想象到他們有不同的名字,記住它們的區別就簡單了。
process.nextTick()
應該是 process.sendThisToTheStartOfTheQueue()
。
setImmediate()
應該被叫做 sendThisToTheEndOfTheQueue()
.
(無關話題:我一直認爲在React中,props
應該被稱爲stuffThatShouldStayTheSameIfTheUserRefreshes
並且state
應該被稱爲stuffThatShouldBeForgottenIfTheUserRefreshes
)
sever.listen作爲一個對象
我喜歡傳遞一個”選擇”參數而不是五個不同名字並且必須特殊排列的參數,其實當運行服務監聽請求的時候你可以這樣做。
require(`http`)
.createServer()
.listen({
port: 8080,
host: `localhost`,
})
.on(`request`, (req, res) => {
res.end(`Hello World!`);
});
這是一個不怎麼光明正大的做法,因爲在http.server文檔中並沒有提及這個,你只能在net.server文檔(http.server繼承自這個文檔)中找到它。
相對路徑
你傳遞到fs模塊的路徑可以使相對路徑。這和process.cwd()
是相關聯的。大多數人或許知道這個,但是我認爲最好用完整路徑。
const fs = require(`fs`);
const path = require(`path`);
// why have I always done this...
fs.readFile(path.join(__dirname, `myFile.txt`), (err, data) => {
// do something
});
// when I could just do this?
fs.readFile(`./path/to/myFile.txt`, (err, data) => {
// do something
});
路徑解析
不需要用各種正則去匹配解析來得到文件名和路徑的擴展,當我需要時我只需要這樣
myFilePath = `/someDir/someFile.json`;
path.parse(myFilePath).base === `someFile.json`; // true
path.parse(myFilePath).name === `someFile`; // true
path.parse(myFilePath).ext === `.json`; // true
用顏色來渲染consloe
可以用console.dir(obj,{colors:true}),打印時對象的props/values會以不同的顏色被打印,可以讓我們更方便查看。
告訴setInterval()待在角落裏
你每天使用setInterval()讓它清理數據庫,通常當setInterval()被掛起時Node’s事件循環不會退出。如果你想讓Node睡眠(我不知道這有什麼效益)你可以這樣做:
const dailyCleanup = setInterval(() => {
cleanup();
}, 1000 * 60 * 60 * 24);
dailyCleanup.unref();
如果你沒有什麼需要掛起(例如沒有http監聽服務),Node不會退出
使用信號常量
如果你喜歡kill,你可能這樣做過:
process.kill(process.pid, `SIGTERM`);
這沒有什麼問題,xxx還可以用一個更粗暴的方式:
process.kill(process.pid, os.constants.signals.SIGTERM);
IP地址確認
有一個叫IP地址驗證器的東西,我曾經寫過正則表達式來做這件事情不止一次,愚蠢啊!
require(
net).isIP(
10.0.0.1)
將會返回4
require(
net).isIP(
cats)
將會返回0
因爲cats不是IP地址。
os.EOL
你曾經硬編碼過行尾的字符嗎?
天啊!
專門爲你,有os.EOL(在windows上是\r\n在別處是\n),切換到os.EOL將會保證你良好的代碼規範。
const fs = require(`fs`);
// bad
fs.readFile(`./myFile.txt`, `utf8`, (err, data) => {
data.split(`\r\n`).forEach(line => {
// do something
});
});
// good
const os = require(`os`);
fs.readFile(`./myFile.txt`, `utf8`, (err, data) => {
data.split(os.EOL).forEach(line => {
// do something
});
});
查找狀態碼
我們需要查找普通HTTP請求的狀態碼和它們的友好的名字。http.STAUS_CODES就是我要說的按個對象,每個key值就是它的狀態碼,相匹配的value值就是我們要閱讀的。因此我們可以這麼做:
someResponse.code === 301; // true
require(`http`).STATUS_CODES[someResponse.code] === `Moved Permanently`; // true
預防不必要的崩潰
我一直認爲下面的代碼會使服務停止時荒唐的:
const jsonData = getDataFromSomeApi(); // But oh no, bad data!
const data = JSON.parse(jsonData); // Loud crashing noise.
爲了預防這愚蠢的會損害你一天的心情的事情發生,你可以process.on(‘uncaughtException’,console.error);放在你的Node app中最頂上的位置。
當然,我是一個理智的人,所以我使用PM2並且把事情放到try…catch中去
需要注意的是,這不是最好的實踐,並且在一個大型項目中可能會是一個壞主意,你要自己去決定你去相信官方文檔還是一些不入流的博客
僅是once()
除了on()之外,對於所有的事件發射器來說還有一個once()方法,
server.once(`request`, (req, res) => res.end(`No more from me.`));
訂製console
你可以創建屬於你自己的console使用 new console.Console(standradOut,errorOut),並且傳入自己的輸出流。
爲什麼?我也不知道。可能你想要創建一個console讓它輸出到文件中,或者套接字,胡總惡化其他的地方。