node_入门,包,流式 (一)
1. node入门
nodeJs是基于chrome V8引擎的一个运行环境
1.1 优点
- 异步非堵塞的I/O
- 事件循环机制
- 事件驱动
- 单线程/跨平台
1.2 缺点
- callback hell
- 单线程, 处理不好CPU密集型任务
2. 模块化
将一个大的功能拆分为一个个小的模块, 通过不同的模块的组合来实现一个大功能。
2.1 优点
- 避免命名冲突(减少命名空间污染)
- 提高代码的复用性, (提升用户体验)
- 方便今后维护代码
-
node中使用的是commonjs的模块化规范
- 引入模块
- require(模块的路径)
- 暴露模块
- module.exports
- exports
- 引入模块
- node中引入模块都是通过require函数引入,总结引入模块的规则:
- 自定义模块:用户自己写的模块,引入路径必须以 ./ 或者 ../开头 后面加上文件的完整路径,否则就会报错
- 核心模块:node中自带的模块 和 通过npm下载的模块 ,引入路径直接写模块名称就OK
-
node中能够解析三种文件:.node .js .json
-
当你通过require函数引入模块时,如果模块名没有后缀名,它会按上面的规则自动补全
//定义模块的内容
function add(x, y) {
return x + y;
}
function mul(x, y) {
return x * y;
}
const love = 'cat';
//暴露模块内容
module.exports = {
add, mul, love
}
/////////
//定义模块的内容
const me = 'eloise';
const you = 'lily';
//暴露模块内容
exports.me = me;
exports.you = you;
var m1 = require('./myModule01'); //函数
console.log(m1); //{ add: [Function: add], mul: [Function: mul], love: 'cat' }
var m2 = require('./myModule02'); //对象
console.log(m2); //{ me: 'eloise', you: 'lily' }
console.log(m1.add(2, 3), m1.mul(2, 3), m1.love); //5 6 'cat'
console.log(m2.me, m2.you); //eloise lily
暴露模块的规则:
- exports 必须以对象点取添加要暴露出去的属性或方法
- module.exports 可以通过直接赋值 也可以等于一个对象,将要暴露出去的内容添加上去
- 用法的区别:
- 在es6出来以后 使用module.exports较多
- node中暴露模块的本质是什么?
- 向外暴露的就是module.exports对象
- exports对象是对module.exports对象的引用
let person = { hobby: {} } let hobby = person.hobby; hobby.drink = 'cola'; console.log(person.hobby); hobby = { game: '吃鸡' } console.log(hobby, person.hobby);
3. function-in-node
- callee返回正在执行的函数本身的引用,它是arguments的一个属性
-
node中的js的组成:
- ES 基本全部实现了
- DOM 没有
- BOM 基本没有(除了console setTimeout setInterval)
- node中的模块默认对外不可见的,因为包裹了一层函数
// console.log(this); //空的对象
// console.log(arguments.callee.toString()); //伪数组 有数组的一般属性 没有数组的方法
/*
function (exports, require, module, __filename, __dirname) {}
exports 暴露模块
require 引入模块
module module.exports 暴露模块
__filename 当前文件的完整路径 绝对路径
__dirname 文件夹的完整路径 绝对路径
*/
console.log(__filename, __dirname);
//C:\Users\web\Desktop\eloise\01\03_function-in-node.js
//C:\Users\web\Desktop\eloise\01
4. global
- 浏览器中有一个全局对象 window
- 三者执行顺序:(事件轮询机制:主要研究6个阶段)
- timers 定时器阶段 开始计时,执行相应回调函数
- pending callbacks 准备阶段
- idle, prepare 错误处理阶段 tcp协议错误...
- poll 轮询阶段
- 如果事件队列有内容
- 轮询事件队列,依次取出队列中第一个回调函数并执行,直到所有的事件队列为空或者达到系统最大限制
- 如果事件队列为空
- 如果之前定义过setImmediate函数, 直接到check阶段
- 如果没有定义过setImmediate函数, 等待,继续轮询事件队列(当定时器到点了,它也会继续下一个阶段,开启新的轮询)
- check 检查阶段 执行setImmediate函数的回调
- close callbacks 关闭阶段
// process.nextTick() 此函数能在任意阶段执行
setImmediate(function () {
console.log('setImmediate()函数执行了');
})
process.nextTick(function () {
console.log('process.nextTick()函数执行了');
})
setTimeout(function () {
console.log('setTimeout()函数执行了');
}, 0)
// process.nextTick()函数执行了
// setTimeout()函数执行了
// setImmediate()函数执行了
5. Buffer
Buffer是一个类数组对象
不同是Buffer是专门用来保存二进制数据的。
// let buf = new Buffer(10); //废弃了 性能差
// console.log(buf);
let buf1 = Buffer.allocUnsafe(10); //方法是不安全的,可能包含敏感数据 但是性能最好
buf1.fill(0);//将内部的数据全部用0填充
console.log(buf1); //<Buffer 98 d5 ef 98 f7 7f 00 00 01 00>
/*
显示16进制数据
00 - ff
0 - 255
0000 0000 - 1111 1111
1 byte(字节) = 8 bit(位)
1 kb = 1024 byte
1 mb = 1024 kb
1 gb = 1024 mb
英文字母和数字 占1个字节
汉字 占3个字节
*/
let buf2 = Buffer.alloc(10); //方法安全的,不包含敏感数据 但是性能较差
console.log(buf2);
let buf3 = Buffer.from('meow meow meow');
// let buf3 = Buffer.from('尚硅谷');
console.log(buf3);
//<Buffer 6d 65 6f 77 20 6d 65 6f 77 20 6d 65 6f 77>
console.log(buf3[0], buf3.length); //109 14 (16=>10)
buf3.forEach(item => {
console.log(item); //(16=>10)
})
6. npm
全称:Node Package Manager , Node的管理包的工具
- cnpm安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
有什么用
- 通过NPM可以对Node的包进行搜索、下载、安装、删除、上传
NPM的常用指令:
- npm -v
查看npm的版本 - npm init
初始化项目的package.json文件 - npm search / s 包名
搜索指定的包 - npm install / i 包名
安装指定的包 - npm install / i 包名 --save
安装指定包并添加到项目的生产依赖中 (cnpm中, 后面一定要加save) - npm install / i 包名 --save-dev
安装指定包并添加到项目的开发依赖中 - npm install / i 包名 -g
全局安装(全局安装都是安装一些工具) - npm install / i
安装项目中的所有依赖 - npm remove / r 包名
删除指定的包
yarn: 是Facebook开源的新的包管理器,可以用来代替npm。
- yarn的特点
有缓存。
没有自己的仓库地址,使用的是npm仓库地址。
npm install cyarn -g --registry "https://registry.npm.taobao.org"
- yarn --version
- yarn init //生成package.json !!!注意生成的包名不能有中文,大写
- yarn global package (全局安装)
- yarn add package (局部安装)
- yarn add package --dev (相当于npm中的--save-dev)
- yarn remove package
- yarn list //列出已经安装的包名
//引入包math
const math = require('math');
console.log(math.add(2, 3));
console.log(math.mul(2, 3));
7. 异步写入文件
fs是什么
全称为file system,所谓的文件系统,就是对计算机中的文件进行增删改查等操作。它是一个服务器的基础,在Node中通过fs模块来操作文件系统。
- fs 文件系统, node中的核心模块
异步写入文件
- 打开文件
-
fs.open(path, flags[, mode], callback)
- path 文件路径
- flags 要对文件进行的操作 w(write) r(read) a(add追加)
- mode 可选值,默认值 0o666
0o111 文件可执行 0o222 文件可以写入 0o444 文件可以读取 0o666 文件可读可写
- callback 回调函数
- err 错误对象 ---- 错误优先机制
- 如果open方法出了问题,err就是错误信息
- 如果方法没有出问题,err就是null
- fd 文件描述符,唯一的
- 写入文件
-
fs.write(fd, string[, position[, encoding]], callback)
- fd 文件描述符
- string 要写入的内容
- position 写入文件的起始位置,可选值,默认值0
- window系统下会自动忽略,不影响flag(add)追加,
- mac系统则不会忽略。从而导致flag(add)无作用
- encoding 编码方法,可选值,默认值'utf8'
- callback 回调函数
- err 错误对象
- written 要写入内容的字节数
- string 写入的内容
- 关闭文件
-
fs.close(fd, callback)
- fd 文件描述符
- callback 回调函数
- err 错误对象
const fs = require('fs');
//打开文件
fs.open('hello.txt', 'w', 0o666, (err, fd) => {
//处理错误
if (!err) {
//open方法没有出错
console.log('open方法执行成功了');
fs.write(fd, '今天天气真情朗', 0, 'utf8', (err, written, string) => {
//处理错误
if (!err) {
//write方法没有出错
console.log('write方法执行成功了');
console.log(written, string);
} else {
//write方法出错了
console.log(err);
}
//不管write方法成不成功,我都要关闭文件
fs.close(fd, err => {
//处理错误
if (!err) {
console.log('close方法执行成功了');
} else {
console.log(err);
}
})
})
} else {
//open方法出错了
console.log(err);
}
})
8. 简单写入文件
-
fs.writeFile(file, data[, options], callback)
- file 要写入的文件
- data 要写入的内容(buffer/string)
- options 可选值 配置对象
- encoding
- mode
- flag
- callback
- err 错误对象
const fs = require('fs');
/*创建要写入的内容*/
let buf = Buffer.from('hellow nodeJs');
// console.log(buf.toString());
fs.writeFile('3.txt', buf, err => {
if(!err) {
console.log('the writeFile success...');
}else {
console.log(err);
}
})
9. 流式写入文件
- 通常针对大文件
-
fs.createWriteStream(path[, options])
- path 文件路径
- options 可选值,配置对象
- flags <string>
- encoding <string>
- fd <integer>
- mode <integer>
- autoClose <boolean> 是否自动关闭,默认值true
- start <integer> 写入起始位置,默认值0
const fs = require('fs');
//执行函数返回一个可写流
const ws = fs.createWriteStream('33.txt');
// //绑定事件监听
ws.on('open', fd => {
console.log('file open success...');
})
ws.on('close', err => {
if(!err){
console.log('file close success');
}
})
//写入内容
ws.write('who can told ');
ws.write('me just to tell ');
ws.write('my school and the flags');
//
// //关闭流
// ws.close();
ws.end();
10. 简单读取文件
-
fs.writeFile(file, data[, options], callback)
- path
- options 可选值 配置对象
- mode
- flag
- callback
- err 错误对象
- data 读取数据
const fs = require('fs');
fs.readFile('package.json', (err, data) => {
if (!err) {
//文件读取成功
console.log(data); //返回值是一个Buffer
console.log(data.toString());
} else {
//文件读取失败
console.log(err);
}
})
11. 流式读取文件
- fs.createReadStream(path[, options])
const fs = require('fs');
//创建可读流
const rs = fs.createReadStream('C:\\Users\\web\\Desktop\\1.mp4');
//创建可写流
const ws = fs.createWriteStream('1.mp4');
//绑定一次性事件
rs.once('open', () => {
console.log('可读流打开了');
})
rs.once('close', () => {
console.log('可读流关闭了');
//可读流将所有数据都读取完毕了,所以要关闭可写流
ws.end();
})
ws.once('open', () => {
console.log('可写流打开了');
})
ws.once('close', () => {
console.log('可写流关闭了');
})
//读取可读流的数据
rs.on('data', data => {
// console.log(data);
// console.log(data.length); //每次读取文件的最大值是 65536 = 64 * 1024 64kb
ws.write(data);
})
//rs.pipe(ws);
网友评论