关于菜鸟教程的node学习笔记

2020-07-10  本文已影响0人  jeneen1129

1. 阻塞与非阻塞

阻塞: 按照代码顺序执行
非阻塞:不按照代码顺序执行

console.log('1 sync&async!')
var fs = require('fs')

var data = fs.readFileSync('callback.txt')  // 阻塞代码
console.log(data.toString())
console.log('readFileSync读取完毕!')
//非阻塞
fs.readFile('callback.txt', function (err, data) {
    if (err) return console.error(err);
    console.log('readFile')
    console.log(data.toString());
});
console.log('读取完毕!')
console.log('1 sync&async!')

2.事件循环

EventEmitter:
on 函数用于绑定事件函数,emit 属性用于触发一个事件
事件监听器回调函数被先后调用

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

console.log('2 events!')
var events = require('events');
const { EventEmitter } = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.on('myclick', function () {
    console.log('you emit myclick')
});
eventEmitter.emit('myclick')
eventEmitter.on('myclick', function (arg1, arg2) {
    console.log('listener1', arg1, arg2);
});
eventEmitter.on('myclick', function (arg1, arg2) {
    console.log('listener2', arg1, arg2);
});
eventEmitter.emit('myclick', 'arg1 参数', 'arg2 参数');
console.log(eventEmitter.listenerCount('myclick'))
console.log('2 events!')

3. 缓冲区(buffer)

用来创建一个专门存放二进制数据的缓存区(TCP流或文件流时,必须使用到二进制数据)
创建方式可以支持多种编码(参数设置)
读取、copy、compare、slice等操作接口
与json互转

/** Buffer 与字符编码``` 
const buf = Buffer.from('runoob', 'ascii');

// 输出 72756e6f6f62
console.log(buf.toString('hex'));

// 输出 cnVub29i
console.log(buf.toString('base64'));

4. 流(stream)

是一个抽象接口
有四种流类型:
Readable - 可读操作。
Writable - 可写操作。
Duplex - 可读可写操作.
Transform - 操作被写入数据,然后读出结果。

// 所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:data\end\error\finish
console.log('4. stream about eventEmitter')
var fs = require("fs");
var data = '';

// 创建可读流
var readerStream = fs.createReadStream('callback.txt');

// 设置编码为 utf8。
readerStream.setEncoding('UTF8');

// 处理流事件 --> data, end, and error
readerStream.on('data', function (chunk) {
    data += chunk;
});

readerStream.on('end', function () {
    console.log(data);
});

readerStream.on('error', function (err) {
    console.log(err.stack);
});
console.log('4. stream about eventEmitter')

管道流

//管道流---管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。
console.log("4. stream about pipe");
var fs = require("fs");

// 创建一个可读流
var readerStream = fs.createReadStream('callback.txt');

// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');

// 管道读写操作
// 读取 callback.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);

console.log("程序执行完毕");
console.log("4. stream about pipe");

链式流

// 链式流---链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。
console.log("4. stream about 链式流");
var fs = require("fs");
var zlib = require('zlib');

// 压缩 callback.txt 文件为 callback.txt.gz
fs.createReadStream('callback.txt')
    .pipe(zlib.createGzip())
    .pipe(fs.createWriteStream('callback.txt.gz'));

console.log("文件压缩完成。");
console.log("4. stream about 链式流");

5. 模块系统

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。
暴露模块: exports.xxx = obj
module.exports = obj
如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports
引入模块: var xxx = require(xxx)
存在 4 类模块(原生模块和3种文件模块)

6. 函数function

Node.js 中函数的使用与 JavaScript 类似

7. 路由(route)

要为路由提供请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码。
因此,我们需要查看 HTTP 请求,从中提取出请求的 URL 以及 GET/POST 参数。这一功能应当属于路由还是服务器(甚至作为一个模块自身的功能)确实值得探讨,但这里暂定其为我们的HTTP服务器的功能。
我们需要的所有数据都会包含在 request 对象中,该对象作为 onRequest() 回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的 Node.JS 模块,它们分别是 url 和 querystring 模块。
url.parse(request.url).pathname/query

console.log("7. analysis route");
var url = require('url');
console.log(url.parse('http://localhost:8888/question').pathname)
console.log(url.parse('http://localhost:8888/question?name=hh&age=1').query)
console.log("7. analysis route");

8. 全局对象(global)

global 最根本的作用是作为全局变量的宿主。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:
在最外层定义的变量;
全局对象的属性;
隐式定义的变量(未定义直接赋值的变量)
有类似以下:
__filename:当前正在执行的脚本的文件名
__dirname:当前执行脚本所在的目录
setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。返回一个代表定时器的句柄值。
->clearTimeout(t)
setInterval(cb, ms), clearInterval(t)
console
process

console.log("8. global value");
console.log(__filename)
console.log(__dirname)
console.log(process.pid)
console.log("8. global value");

9. 常用工具 util

util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的功能 过于精简的不足。

console.log("9. util");
const util = require('util');
async function fn() {
    return 'hello world';
}
const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
    if (err) throw err;
    console.log(ret);
});
console.log("9. util");

10. 文件系统

提供一组类似 UNIX(POSIX)标准的文件操作API
fs模块:
api: readFile、readFileSync、open、close、stat等等类似c语言

11. GET/POST请求

get: response.end(util.inspect(url.parse(req.url, true)));
post:

// 定义了一个post变量,用于暂存请求体的信息
    var post = '';

    // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
    req.on('data', function(chunk){
        post += chunk;
    });

    // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
    req.on('end', function(){
        post = querystring.parse(post);
        res.end(util.inspect(post));
    });

12. Node.js 工具模块

在 Node.js 模块库中有很多好用的模块。接下来我们为大家介绍几种常用模块的使用:
1   OS 模块
    提供基本的系统操作函数。
2   Path 模块
    提供了处理和转换文件路径的工具。
3   Net 模块
    用于底层的网络通信。提供了服务端和客户端的的操作。
4   DNS 模块
    用于解析域名。
5   Domain 模块
    简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的。

13. web模块

搭建web服务器:http.createServer().listen()
搭建web客户端:http.request()

14. express (必学)

官网:http://expressjs.com/
API:http://expressjs.com/zh-cn/4x/api.html
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:
可以设置中间件来响应 HTTP 请求。
定义了路由表用于执行不同的 HTTP 请求动作。
可以通过向模板传递参数来动态渲染 HTML 页面。
安装expres: npm install express --save(cnpm)
需要一起安装:cnpm install body-parser --save
cnpm install cookie-parser --save
cnpm install multer --save
使用:

//express_demo.js 文件
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser())
// 设置静态文件资源
app.use('/public', express.static('public'));
// request 和 response 对象有很多api
app.get('/', function (req, res) {
   res.send('Hello World');
})
ar server = app.listen(8081, function () {}

可以实现post\get\文件上传\cookies管理

15.restful API

架构风格
是一些约定与约束

16.Node.js 多进程

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

每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象。

Node 提供了 child_process 模块来创建子进程,方法有:

exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。

spawn - child_process.spawn 使用指定的命令行参数创建新进程。

fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['./son.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。

上一篇下一篇

猜你喜欢

热点阅读