虽然我已经用了三年多的NodeJS,也曾经以为自己对其无所不知。但是我好像从未有安静的坐下来仔细地阅读NodeJS的完整文档。如果有熟悉我的朋友应该知道,我之前已经看了HTML,DOM,Web APIs,CSS,SVG以及ECMAScript的文档,NodeJS是我这个系列的最后一个待翻阅的山峰。在阅读文档的过程中我也发现了很多本来不知道的知识,我觉得我有必要分享给大家。不过文档更多的是平铺直叙,因此我也以阅读的顺序列举出我觉得需要了解的点。

10年的和政网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销的优势是能够根据用户设备显示端的尺寸不同,自动调整和政建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“和政网站设计”,“和政网站推广”以来,每个客户项目都认真落实执行。
querystring:可以用作通用解析器的模块
很多时候我们会从数据库或其他地方得到这种奇怪格式的字符串:name:Sophie;shape:fox;condition:new,一般来说我们会利用字符串切割的方式来讲字符串划分到JavaScript Object。不过querystring也是个不错的现成的工具:
- const weirdoString = `name:Sophie;shape:fox;condition:new`;
 - const result = querystring.parse(weirdoString, `;`, `:`);
 - // result:
 - // {
 - // name: `Sophie`,
 - // shape: `fox`,
 - // condition: `new`,
 - // };
 
V8 Inspector
以--inspect参数运行你的Node应用程序,它会反馈你某个URL。将该URL复制到Chrome中并打开,你就可以使用Chrome DevTools来调试你的Node应用程序啦。详细的实验可以参考这篇文章。不过需要注意的是,该参数仍然属于实验性质。
nextTick 与 setImmediate的区别
这两货的区别可能光从名字上还看不出来,我觉得应该给它们取个别名:
再说句不相关的,React中的Props应该为stuffThatShouldStayTheSameIfTheUserRefreshes,而State应该为stuffThatShouldBeForgottenIfTheUserRefreshes。
Server.listen 可以使用Object作为参数
我更喜欢命名参数的方式调用函数,这样相较于仅按照顺序的无命名参数法会更直观。别忘了Server.listen也可以使用某个Object作为参数:
- require(`http`)
 - .createServer()
 - .listen({
 - port: 8080,
 - host: `localhost`,
 - })
 - .on(`request`, (req, res) => {
 - res.end(`Hello World!`);
 - });
 
不过这个特性不是表述在http.Server这个API中,而是在其父级net.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
 - });
 
Path Parsing:路径解析
之前我一直不知道的某个功能就是从某个文件名中解析出路径,文件名,文件扩展等等:
- myFilePath = `/someDir/someFile.json`;
 - path.parse(myFilePath).base === `someFile.json`; // true
 - path.parse(myFilePath).name === `someFile`; // true
 - path.parse(myFilePath).ext === `.json`; // true
 
Logging with colors
别忘了console.dir(obj,{colors:true})能够以不同的色彩打印出键与值,这一点会大大增加日志的可读性。
使用setInterval执行定时任务
我喜欢使用setInterval来定期执行数据库清理任务,不过默认情况下在存在setInterval的时候NodeJS并不会退出,你可以使用如下的方法让Node沉睡:
- const dailyCleanup = setInterval(() => {
 - cleanup();
 - }, 1000 * 60 * 60 * 24);
 - dailyCleanup.unref();
 - Use Signal Constants
 
如果你尝试在NodeJS中杀死某个进程,估计你用过如下语法:
- process.kill(process.pid, `SIGTERM`);
 
这个没啥问题,不过既然第二个参数同时能够使用字符串与整形变量,那么还不如使用全局变量呢:
- process.kill(process.pid, os.constants.signals.SIGTERM);
 
IP Address Validation
NodeJS中含有内置的IP地址校验工具,这一点可以免得你写额外的正则表达式:
- require(`net`).isIP(`10.0.0.1`) 返回 4
 - require(`net`).isIP(`cats`) 返回 0
 
os.EOF
不知道你有没有手写过行结束符,看上去可不漂亮啊。NodeJS内置了os.EOF,其在Windows下是rn,其他地方是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 状态码
NodeJS帮我们内置了HTTP状态码及其描述,也就是http.STATUS_CODES,键为状态值,值为描述:
你可以按照如下方法使用:
- 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);
 
当然,这种办法绝不是最佳实践,如果是在大型项目中我还是会使用PM2,然后将所有可能崩溃的代码加入到try...catch中。
Just this once()
除了on方法,once方法也适用于所有的EventEmitters,希望我不是最后才知道这个的:
- server.once(`request`, (req, res) => res.end(`No more from me.`));
 
Custom Console
你可以使用new console.Console(standardOut,errorOut),然后设置自定义的输出流。你可以选择创建console将数据输出到文件或者Socket或者第三方中。
DNS lookup
某个年轻人告诉我,Node并不会缓存DNS查询信息,因此你在使用URL之后要等个几毫秒才能获取到数据。不过其实你可以使用dns.lookup()来缓存数据:
- dns.lookup(`www.myApi.com`, 4, (err, address) => {
 - cacheThisForLater(address);
 - });
 
fs 在不同OS上有一定差异
net 模块差不多比http快上两倍
笔者在文档中看到一些关于二者性能的讨论,还特地运行了两个服务器来进行真实比较。结果来看http.Server大概每秒可以接入3400个请求,而net.Server可以接入大概5500个请求。
- // This makes two connections, one to a tcp server, one to an http server (both in server.js)
 - // It fires off a bunch of connections and times the response
 - // Both send strings.
 - const net = require(`net`);
 - const http = require(`http`);
 - function parseIncomingMessage(res) {
 - return new Promise((resolve) => {
 - let data = ``;
 - res.on(`data`, (chunk) => {
 - data += chunk;
 - });
 - res.on(`end`, () => resolve(data));
 - });
 - }
 - const testLimit = 5000;
 - /* ------------------ */
 - /* -- NET client -- */
 - /* ------------------ */
 - function testNetClient() {
 - const netTest = {
 - startTime: process.hrtime(),
 - responseCount: 0,
 - testCount: 0,
 - payloadData: {
 - type: `millipede`,
 - feet: 100,
 - test: 0,
 - },
 - };
 - function handleSocketConnect() {
 - netTest.payloadData.test++;
 - netTest.payloadData.feet++;
 - const payload = JSON.stringify(netTest.payloadData);
 - this.end(payload, `utf8`);
 - }
 - function handleSocketData() {
 - netTest.responseCount++;
 - if (netTest.responseCount === testLimit) {
 - const hrDiff = process.hrtime(netTest.startTime);
 - const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6;
 - const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString();
 - console.info(`net.Server handled an average of ${requestsPerSecond} requests per second.`);
 - }
 - }
 - while (netTest.testCount < testLimit) {
 - netTest.testCount++;
 - const socket = net.connect(8888, handleSocketConnect);
 - socket.on(`data`, handleSocketData);
 - }
 - }
 - /* ------------------- */
 - /* -- HTTP client -- */
 - /* ------------------- */
 - function testHttpClient() {
 - const httpTest = {
 - startTime: process.hrtime(),
 - responseCount: 0,
 - testCount: 0,
 - };
 - const payloadData = {
 - type: `centipede`,
 - feet: 100,
 - test: 0,
 - };
 - const options = {
 - hostname: `localhost`,
 - port: 8080,
 - method: `POST`,
 - headers: {
 - 'Content-Type': `application/x-www-form-urlencoded`,
 - },
 - };
 - function handleResponse(res) {
 - parseIncomingMessage(res).then(() => {
 - httpTest.responseCount++;
 - if (httpTest.responseCount === testLimit) {
 - const hrDiff = process.hrtime(httpTest.startTime);
 - const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6;
 - const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString();
 - console.info(`http.Server handled an average of ${requestsPerSecond} requests per second.`);
 - }
 - });
 - }
 - while (httpTest.testCount < testLimit) {
 - httpTest.testCount++;
 - payloadData.test = httpTest.testCount;
 - payloadData.feet++;
 - const payload = JSON.stringify(payloadData);
 - options[`Content-Length`] = Buffer.byteLength(payload);
 - const req = http.request(options, handleResponse);
 - req.end(payload);
 - }
 - }
 - /* -- Start tests -- */
 - // flip these occasionally to ensure there's no bias based on order
 - setTimeout(() => {
 - console.info(`Starting testNetClient()`);
 - testNetClient();
 - }, 50);
 - setTimeout(() => {
 - console.info(`Starting testHttpClient()`);
 - testHttpClient();
 - }, 2000);
 - // This sets up two servers. A TCP and an HTTP one.
 - // For each response, it parses the received string as JSON, converts that object and returns a string
 - const net = require(`net`);
 - const http = require(`http`);
 - function renderAnimalString(jsonString) {
 - const data = JSON.parse(jsonString);
 - return `${data.test}: your are a ${data.type} and you have ${data.feet} feet.`;
 - }
 - /* ------------------ */
 - /* -- NET server -- */
 - /* ------------------ */
 - net
 - .createServer((socket) => {
 - socket.on(`data`, (jsonString) => {
 - socket.end(renderAnimalString(jsonString));
 - });
 - })
 - .listen(8888);
 - /* ------------------- */
 - /* -- HTTP server -- */
 - /* ------------------- */
 - function parseIncomingMessage(res) {
 - return new Promise((resolve) => {
 - let data = ``;
 - res.on(`data`, (chunk) => {
 - data += chunk;
 - });
 - res.on(`end`, () => resolve(data));
 - });
 - }
 - http
 - .createServer()
 - .listen(8080)
 - .on(`request`, (req, res) => {
 - parseIncomingMessage(req).then((jsonString) => {
 - res.end(renderAnimalString(jsonString));
 - });
 - });
 
REPL tricks
                新闻标题:我在阅读NodeJS文档中读出的19个套路
                
                网页网址:http://www.csdahua.cn/qtweb/news5/216455.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网