NodeJS基础

linux上nodejs的运行权限问题,在申请监听某些端口需要sudo权限(1024以下)。

模块的概念。编写复杂的程序时,为了划分功能及提高可重用、可维护性,将程序分成不同的模块来编写,是一个非常重要的概念。

模块的导入:require。

导出:exports。

初始化,模块仅被导入一次,之后会被缓存起来以供重复利用。

二进制模块,c/c++编写,.node 后缀,可以利用系统提供的更多API,但是不容易编写,跨平台使用也有一些问题。


代码组织和部署

模块的路径解析机制

  • 绝对路径
  • 相对路径
  • 还有:内置模块、node_modules 目录下的模块加载

一个模块中使用require(‘foo/bar’)方式加载模块时,则NodeJS依次尝试使用以下路径。

 /home/user/node_modules/foo/bar
 /home/node_modules/foo/bar
 /node_modules/foo/bar

或者指定 NODE_PATH 环境变量。
NODE_PATH 环境变量中包含一到多个目录路径,路径之间在Linux下使用 ':' 分隔,在 Windows 下使用 ';' 分隔。

包的代码、目录结构组织。

入口模块 index.js 文件名使整个模块以模块目录作为入口。

package.json 自定义入口模块文件名和路径。

命令行程序

  • linux

1)js文件顶部加上解析器注释
2)js文件加运行权限
3)创建软连接到PATH环境变量目录

  • windows

1)新建cmd文件在js文件相同目录下
2)确保cmd文件所在目录已加入PATH环境变量

工程目录

package.json 中, 指定命令行运行指令和命令行运行文件

  "bin": {
        "node-echo": "./bin/node-echo"
    }

本地安装测试:

mrldeMBP:node-echo mrl$ sudo npm i . -g
/usr/local/bin/node-echo -> /usr/local/lib/node_modules/node-echo/bin/node-echo

+ node-echo@1.0.0
added 1 package in 0.628s

可知,在 /usr/local/bin/ 创建了一个软连接叫做 node-echo,它指向了 node-echo 项目的命令行程序在本地 node 全局安装模块目录中的位置,所以,命令行输入 node-echo 即调用这个 node 命令行程序。

mrldeMBP:node-echo mrl$ node-echo hello hi
hello hi

NPM

语义版本号:

语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号

还有一个包管理器 yarn,有一些NPM没有的优点, 如缓存软件包、对于依赖的一致性保障


文件操作

大、小文件复制

为避免内存被撑爆,大文件应边读边写。

Buffer

nodejs新增了对二进制数据的处理。slice操作将改变原二进制对象。nodejs对buffer的操作更像是指针操作。

Stream(数据流)

用流的方式,通过回调函数传递事件,判断每次的读、写情况,进而控制下一次的写入。

File System(文件系统)

异步版本(大量使用回调函数、err、data参数的传入)、同步版本的使用方法。

Path

path.normalize(),将传入路径参数转换为标准路径。
坑:处理windows的路径差异,替换 ‘\’ 为 ‘/‘

path.join 和 path.extname。

文件编码

utf-8去除BOM

GBK转utf8

单字节编码,utf8和gbk对于英文字符的编码是一样的,可以忽略utf8下中文乱码,对正常的英文字符进行处理,不影响其他看起来是乱码的字符。nodejs中的binary编码可以实现这个方法。

网路操作

http

https

多个证书、多域名,测试类型自制证书支持

url

解析url字符串为对象以获取各部分,根据url对象构建url字符串,拼接url

Query String

参数字符串与参数对象的转换

Zlib

数据压缩与解压

Net

Net模块用于创建socket服务器/客户端

headers驼峰、http服务器的chunk传输方式

进程管理

调用终端命令

var child_process = require('child_process');
var util = require('util');

function copy(source, target, callback) {
    child_process.exec(
        util.format('cp -r %s/* %s', source, target), callback);
}

copy('a', 'b', function (err) {
    // ...
});

Process

全局对象

Child Process

创建和控制子进程

Cluster

充分利用多核cpu,简化多进程服务器程序的开发

获取命令行参数

process.argv,头两个元素是执行程序和主模块文件的路径
main(process.argv.slice(2))让使用方式更自然。

退出程序并设置状态码

process.exit(1)

控制输入输出

标准输入、输出、错误流。

proccess.stdin、process.stdout、process.stderr

降权

完成1024以下端口的监听后,如何取消程序的root权限

创建子进程

var childProcess = child_process.spawn(‘node’, [‘xxx.js’]);

spawn方法支持三个参数。

进程间通讯

守护子进程

异步编程

回调

特殊函数、平行线程

代码设计模式

1)函数返回值

2)遍历数组

串行、并行处理后回调

异常处理

try…catch 一般的编写方式只适用于同步代码

可以通过改造来适应 nodejs 的设计风格。一般要在异常冒泡到执行路径被打断前用try语句捕获异常。

一般回调函数中第一个参数都是err。

process 对象的 uncaughtException 事件可以捕获全局异常,被打断执行路径的异常可以被捕获。

domian模块方便了多重回调函数的异常捕获,使代码变得更简洁。

陷阱

被 process 的 uncaughtException 事件捕获的异常和d omain 对象捕获的子域异常,都应该在处理异常后重启程序。因为发生异常后的程序会处于一个不确定的状态。

大实例

像循环一样的自运行函数

配置文件的设置和作为程序参数的传入

边读取边输出响应

只读数据流简化代码

守护进程

创建子进程来启动程序,并且根据程序退出状态来判断是否需要重启程序
主进程、子进程之间的通信、http服务器的关闭

部署

项目目录,启动、关闭程序的sh脚本

总结

熟悉文档。不可能记住每个细节,但是可以熟悉文档的大概结构,有问题应该到哪里找办法解决。

设计->实现->设计

理智对待第三方包

最值得学习的是异步编程思想、回调函数的使用,还有js异步编程中的异常处理问题。

参考:nodejs