开篇

简介
Node.js是javascript的一个运行环境,使用的语言自然也是javascript。安装之后,可以在控制台直接输入node进入执行环境(也就是直接输入js语句可以执行,退出按两次ctrl + c)。你也可以创建一个js文件,然后在控制台输入node filename.js执行这个文件。

Node.js REPL(交互式解释器)

  • Node REPL 支持输入多行表达式,Node 会自动检测是否为连续的表达式(你只需回车换行即可)
  • 可以使用下划线(_)获取上一个表达式的运算结果

REPL 命令:

  • ctrl + c - 退出当前终端。
  • ctrl + c 按下两次 - 退出 Node REPL。
  • ctrl + d - 退出 Node REPL.
  • 向上/向下 键 - 查看输入的历史命令
  • tab 键 - 列出当前命令
  • .help - 列出使用命令
  • .break - 退出多行表达式
  • .clear - 退出多行表达式
  • .save filename - 保存当前的 Node REPL 会话到指定文件
  • .load filename - 载入当前 Node REPL 会话的文件内容。

搭建服务器
Node.js可以直接搭建服务器端,这对于一个对后端语言有深深恐惧感,但又想要拥有能自己控制的server的前端媛来说简直是巨大的福音,因为,可以用js来搭建server了!并且非常简单。看一个例子就知道了:

1
2
3
4
5
6
7
var http = require('http');
http.createServer(function(request, response){
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World!\n');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

NPM
NPM是随同NodeJS一起安装的包管理工具

查看所有npm的命令:
npm help

使用npm安装模块:
nmp install <moduleName>(本地安装)
npm install <modulaName> -g(全局安装)

查看所有全局安装的模块:
npm list -g

查看某个模块的版本号:
npm list <moduleName>

卸载模块:
npm uninstall <moduleName>

卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:
npm ls

更新模块:
npm update <moduleName>

搜索模块:
npm search <moduleName>

创建模块:
使用 NPM 生成 package.json 文件(以后进阶再仔细研究)

package.json
package.json位于模块的目录下,用于定义包的属性

  • name - 包名。
  • version - 包的版本号。
  • description - 包的描述。
  • homepage - 包的官网 url 。
  • author - 包的作者姓名。
  • contributors - 包的其他贡献者姓名。
  • dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
  • repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
  • main - main 字段指定了程序的主入口文件,require(‘moduleName’) 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
  • keywords - 关键字

主要内容

Node.js 回调函数
回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数

Node.js 事件循环
在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数

Node.js EventEmitter
events 模块只提供了一个对象:events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装
EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发

1
2
3
4
5
6
7
8
var EventEmitter = require('events').EventEmitter; 
var event = new EventEmitter();
event.on('some_event', function() {
console.log('some_event 事件触发');
});
setTimeout(function() {
event.emit('some_event');
}, 1000);

EventEmitter的属性:
addListener on once removeListener removeAllListeners setMaxListeners listeners

类方法:
listenerCount

事件:
newListener removeListener

EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到异常的时候通常会触发 error 事件。
当 error 被触发时,EventEmitter 规定如果没有响应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。

Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

Node.js Stream(流)
Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。
从流中读数据 将数据写入流
管道流 用于从一个流中获取数据并将数据传递到另外一个流中
链式流 可以对流进行压缩、解压等处理

Node.js模块系统
为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript代码、JSON或者编译过的C/C++扩展。

1
2
3
4
5
6
7
8
9
10
11
12
13
//创建模块 hello.js
exports.world = function() {
console.log('hello world');
}
//或者:
module.exports = function() {
console.log('hello world');
}
//或者:
function Hello() {
console.log('hello world');
}
module.exports = Hello;
1
2
3
//引用模块 main.js
var Hello = require('./hello');//./表示当前目录,省略了文件名后缀.js
hello = new Hello();

Node.js 函数
在JavaScript中,一个函数可以作为另一个函数的参数。我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数。

Node.js 路由
通过请求的path name来决定作什么样的response

1
2
3
4
5
//router.js
function route(pathname) {
console.log('About to route a request for ' + pathname);
}
exports.route = route;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//server.js
var http = require('http');
var url = require('url');

function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log('Request for ' + pathname + ' received.');

route(pathname);

response.write(200, {'Content-Type': 'text/plain'});
response.write('hello world');
response.end();
}

http.createServer(onRequest).listen(8888);
console.log('Server has started.');
}

exports.start = start;
1
2
3
4
5
//index.js
var server = require('./server');
var router = require('./router');

server.start(router.route);

Node.js 全局对象
Node.js 中的全局对象是 global,可以直接访问到 global 的属性,而不需要在应用中包含它

  • __filename 表示当前正在执行的脚本的文件名,它将输出文件所在位置的绝对路径
  • __dirname 表示当前执行脚本所在的目录
  • setTimeout(cb, ms)
  • clearTimeout(t)
  • setInterval(cb, ms)
  • console
  • process用于描述当前Node.js 进程状态的对象
console方法 描述
console.log([data][, …]) 向标准输出流打印字符并以换行符结束(可以加%d那种)
console.info([data][, …]) 信息性消息(蓝色的惊叹号)
console.error([data][, …]) 错误消息(红色的叉子)
console.warn([data][, …]) 警告消息(黄色的惊叹号)
console.dir(obj[, options]) 用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示
console.time(label) 输出时间,表示计时开始
console.timeEnd(label) 结束时间,表示计时结束
console.trace(message[, …]) 当前执行的代码在堆栈中的调用路径
console.assert(value[, message][, …]) 用于判断某个表达式或变量是否为真,接收两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果

Node.js 常用工具

  • util.inherits实现对象间原型继承,仅仅继承在原型中定义的函数,构造函数内的不继承
  • util.inspect将任意对象转换为字符串
  • util.isArray(object) util.isRegExp(object) util.isDate(object) util.isError(object)

Node.js 文件系统
https://www.runoob.com/nodejs/nodejs-fs.html

Node.js GET/POST请求
https://www.runoob.com/nodejs/node-js-get-post.html

Node.js Web 模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//创建服务端server.js
var http = require('http');
var fs = require('fs');
var url = require('url');

// 创建服务器
http.createServer( function (request, response) {
// 解析请求,包括文件名
var pathname = url.parse(request.url).pathname;

// 输出请求的文件名
console.log("Request for " + pathname + " received.");

// 从文件系统中读取请求的文件内容
fs.readFile(pathname.substr(1), function (err, data) {
if (err) {
console.log(err);
// HTTP 状态码: 404 : NOT FOUND
// Content Type: text/plain
response.writeHead(404, {'Content-Type': 'text/html'});
}else{
// HTTP 状态码: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/html'});

// 响应文件内容
response.write(data.toString());
}
// 发送响应数据
response.end();
});
}).listen(8080);

// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8080/');

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//创建客户端client.js
//新打开一个终端,执行client.js
var http = require('http');

// 用于请求的选项
var options = {
host: 'localhost',
port: '8080',
path: '/index.html'
};

// 处理响应的回调函数
var callback = function(response){
// 不断更新数据
var body = '';
response.on('data', function(data) {
body += data;
});

response.on('end', function() {
// 数据接收完成
console.log(body);
});
}
// 向服务端发送请求
var req = http.request(options, callback);
req.end();

Node.js Express 框架
https://www.runoob.com/nodejs/nodejs-express-framework.html
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站.

Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求
  • 定义了路由表用于执行不同的 HTTP 请求动作
  • 可以通过向模板传递参数来动态渲染 HTML 页面

Node.js 多进程
我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。

Node.js 连接 MySQL
https://www.runoob.com/nodejs/nodejs-mysql.html

Node.js 连接 MongoDB
https://www.runoob.com/nodejs/nodejs-mongodb.html