课程目标
- 掌握异步I/O概念
- promisify用法、流、buffer
- 掌握一个简单http服务(页面、json数据、静态资源)
- 实战一个cli工具(vue路由约定)
Nodejs是一个异步的事件驱动的javascript运行时 特性:非阻塞 I/o 事件操作类比学习运行时这个概念JRE java运行时概念C Runtime .NET Common Language Runtime 运行时rumtime就是程序运行的时候,运行时库就是程序运行的时候所需要依赖的库,运行的时候指的是指令加载到内存并由cpu执行的时候,C代码编译成可执行文件的时候,指令没有被cpu执行,这个时候算是编译时,就是编译的时候。
与前端的不同 :js核心语法不变 前端是操作BOM DOM 后端是fs http buffer event os
看一下核心API:
fs 文件系统
// 03-fs.js
const fs = require('fs');
// 同步调用
const data = fs.readFileSync('./conf.js'); //代码会阻塞在这里 console.log(data);
// 异步调用
fs.readFile('./conf.js', (err, data) => {
if (err) throw err;
console.log(data);
})
// promisify
const {promisify} = require('util')
const readFile = promisify(fs.readFile)
readFile('./conf.js').then(data=>console.log(data))
// fs Promises API node v10
const fsp = require("fs").promises;
fsp
.readFile("./confs.js")
.then(data => console.log(data))
.catch(err => console.log(err));
// async/await
(async () => {
const fs = require('fs')
const { promisify } = require('util')
const readFile = promisify(fs.readFile)
const data = await readFile('./index.html')
console.log('data',data)
})()
// 引用方式 Buffer.from(data).toString('utf-8')
fs阻塞代码实例 和 非阻塞代码实例
EventEmitter
imageEventEmitter 的核心就是事件触发与事件监听器功能的封装
Buffer缓冲区
Buffer - 用于在 TCP 流、文件系统操作、以及其他上下文中与八位字节流进行交互。 八位字节组 成的数组,可以有效的在JS中存储二进制数据
// 04-buffer.js
// 创建一个长度为10字节以0填充的Buffer
const buf1 = Buffer.alloc(10); console.log(buf1);
// 创建一个Buffer包含ascii.
// ascii 查询 http://ascii.911cha.com/
const buf2 = Buffer.from('a') console.log(buf2,buf2.toString())
// 创建Buffer包含UTF-8字节
// UFT-8:一种变长的编码方案,使用 1~6 个字节来存储;
// UFT-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
// UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变
const buf3 = Buffer.from('Buffer创建方法');
console.log(buf3);
// 写入Buffer数据 buf1.write('hello');
console.log(buf1);
// 读取Buffer数据
console.log(buf3.toString());
// 合并Buffer
const buf4 = Buffer.concat([buf1, buf3]);
console.log(buf4.toString());
// 可以尝试修改fs案例输出文件原始内容
Buffer类似数组,所以很多数组方法它都有 GBK 转码 iconv-lite
http服务
创建一个http服务器,05-http.js
const http = require('http');
const server = http.createServer((request, response) => {
console.log('there is a request');
response.end('a response from server');
});
server.listen(3000);
// 打印原型链
function getPrototypeChain(obj) {
var protoChain = [];
while (obj = Object.getPrototypeOf(obj)) {//返回给定对象的原型。如果没有继承属 性,则返回 null 。
protoChain.push(obj);
}
protoChain.push(null);
return protoChain;
}
显示一个首页
const {url, method} = request;
if (url === '/' && method === 'GET') {
fs.readFile('index.html', (err, data) => {
if (err) {
response.writeHead(500, { 'Content-Type':'text/plain;charset=utf-8' });
response.end('500,服务器错误');
return ;
}
response.statusCode = 200;
response.setHeader('Content-Type', 'text/html');
response.end(data);
});
} else {
response.statusCode = 404;
response.setHeader('Content-Type', 'text/plain;charset=utf-8');
response.end('404, 页面没有找到');
} else if (url === '/users' && method === 'GET') {
response.writeHead(200, { 'Content-Type': 'application/json' });
response.end(JSON.stringify([{name:'tom',age:20}]));
}
module
Node.js 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。
查看详情
Stream流
stream - 是用于与node中流数据交互的接口
//二进制友好,图片操作,06-stream.js
const fs = require('fs')
const rs2 = fs.createReadStream('./01.jpg')
const ws2 = fs.createWriteStream('./02.jpg') rs2.pipe(ws2);
//响应图片请求,05-http.js
const {url, method, headers} = request;
else if (method === 'GET' && headers.accept.indexOf('image/*') !== -1) {
fs.createReadStream('.'+url).pipe(response);
}
Accept代表发送端(客户端)希望接受的数据类型。 比如:Accept:text/xml; 代表客户端希望 接受的数据类型是xml类型。
Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。 比如:Content- Type:text/html; 代表发送端发送的数据格式是html。
二者合起来, Accept:text/xml; Content-Type:text/html ,即代表希望接受的数据类型是xml格 式,本次请求发送的数据的数据格式是html。
约定路由功能
- loader 文件扫描
- 代码模板渲染 hbs Mustache风格模板
const fs = require('fs')
const handlebars = require('handlebars')
const chalk = require('chalk')
module.exports = async () => {
// 获取页面列表 const list =
fs.readdirSync('./src/views')
.filter(v => v !== 'Home.vue')
.map(v => ({
name: v.replace('.vue', '').toLowerCase(),
file: v }))
// 生成路由定义
compile({
list
}, './src/router.js', './template/router.js.hbs')
// 生成菜单
compile({
list
}, './src/App.vue', './template/App.vue.hbs')
/**
* 编译模板文件
* @param meta 数据定义
* @param filePath 目标文件路径
* @param templatePath 模板文件路径
*/
function compile(meta, filePath, templatePath) {
if (fs.existsSync(templatePath)) {
const content = fs.readFileSync(templatePath).toString();
const result = handlebars.compile(content)(meta);
fs.writeFileSync(filePath, result);
}
console.log(chalk.green(`🚀${filePath} 创建成功`)) }
}
//发布npm
#!/usr/bin/env bash
npm config get registry # 检查仓库镜像库
npm config set registry=http://registry.npmjs.org
echo '请进行登录相关操作:'
npm login # 登陆
echo "-------publishing-------"
npm publish # 发布
npm config set registry=https://registry.npm.taobao.org # 设置为淘宝镜像 echo "发布完成"
exit
常用工具
util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足
1 util.inherits 是一个实现对象间原型继承的函数
2 util.inspect 是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象
3 util.isArray(object) 如果给定的参数 "object" 是一个数组返回true,否则返回false
4 util.isRegExp(object) 如果给定的参数 "object" 是一个正则表达式返回true,否则返回false
5 util.isDate(object) 如果给定的参数 "object" 是一个日期返回true,否则返回false
6 util.isError(object) 如果给定的参数 "object" 是一个错误对象返回true,否则返回false
Express 框架
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:
可以设置中间件来响应 HTTP 请求。
定义了路由表用于执行不同的 HTTP 请求动作。
可以通过向模板传递参数来动态渲染 HTML 页面。
网友评论