node学习笔记

25 阅读8分钟

1. let 和 var

let:不能重复声明
var:可先使用,后声明 (变量提升)

2. 定时器的this指向

先用一个变量接收一下 this

var _this = this;
setTimeout(function() {
  console.log(_this);
}, 600);

ES6 语法:箭头函数

setTimeout(() => {
  console.log(this);
}, 600);

3. try catch 错误处理

正常时执行 try,报错时执行 catch

try{
  console.log(data);
}catch(err){
  console.log(err);
}

4. ES6 扩展方法

1. symbool

{
  // 生成一个值,参数是“描述”,如果参事是字符串,相同的描述生成的值也不等
  let i1 = Symbol("100");
  let i2 = Symbol("100");
  console.log(i1==i2);
}

{
  // 生成一个唯一值,如果参数是Number,参数相同,值也相等
  let i1 = Symbol.for(10); 
  let i2 = Symbol.for(10);
  let i3 = Symbol.for(100);
  console.log(i1==i2 || i2==i3);
  
  // 根据值获取描述
  console.log(Symbol.keyFor(i1));
  console.log(Symbol.keyFor(i2));
  console.log(Symbol.keyFor(i3));
}

2. set

let setArr = new Set();

// 添加
setArr.add(10);
setArr.add(20);
setArr.add(30);
setArr.add('10');
console.log(setArr);
// 删除
setArr.delete('10');
console.log(setArr);
// 清空
setArr.clear();
console.log(setArr);
// 查询
console.log(setArr.has(10));
console.log(setArr.keys());
console.log(setArr.values());
// 遍历
setArr.forEach((item) => {
  console.log(item);
});

3. map

修改时用 set 方法,有就修改,没有就添加

let map = new Map();

// 添加
map.set("name", "node");
map.set("age", 18);
// 删除
map.delete('name');
// 修改
map.set('age', 24);
console.log(map);
// 查询
console.log(map.has('name'));	//查询 -> 返回布尔
console.log(map.get('age'));	//获取 -> 返回值
console.log(map.keys());		//返回所有的key
console.log(map.values());		//返回所有的value
// 遍历
// value: name
// key:node
// entry:Map { 'name' => 'node', 'age' => 24 }
map.forEach((value, key, entry)=>{
  console.log(value, key, entry);
});

5. generator 函数

函数多个返回值:

  1. yield:依次返回,除了最后一个
  2. return:返回最后一个
function* func() {
  var x1 = yield 10*10;
  var x2 = yield x1*20;
  var x3 = yield x2*30;
  var x4 = (yield x3*10)*10;
  return x4;
}

let f = func();
console.log(f.next());    // 10*10 = 100
console.log(f.next(10));  // 10*20 = 200
console.log(f.next(20));  // 20*30 = 600
console.log(f.next(30));  // 30*10 = 300
console.log(f.next(40));  // 40*10 = 400
/* 返回值
{ value: 100, done: false }
{ value: 200, done: false }
{ value: 600, done: false }
{ value: 300, done: false }
{ value: 400, done: true }
*/

6. 同步和异步

  1. 同步:指在一个程序线上,当发生阻塞时,会停止不动,等到返回后,再继续执行
    • 在一条线上,前面的堵了,后面的也堵了
  2. 异步:指在一个程序线上,当发生阻塞时,会分出一条线执行下面的,不会阻塞住停止不动
    • 能分线,前面的堵了,后面的不堵

执行顺序:

  1. 执行 func (generator函数)的第一个 yield,执行定时器
  2. 到时间后执行定时器中的 第二个 yield,执行 cfunc(普通函数)
  3. 打印内容
function* func() {
  yield setTimeout(() => {		// 4
    f.next();
  }, 2000);
  yield cfunc();				// 5
}

console.log("开始执行...");		  // 1
var f = func();					// 2
f.next();						// 3
function cfunc() {				// 6
  console.log("这是后续执行函数");
}

7. promise

1. 基础使用

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => {
    resolve("成功");	// 成功状态
    reject();		 // 失败状态
  }, 2000);
});

promise.then((msg) => {
  console.log(msg);
}).catch(() => {
  console.log("失败");
})

2. 数据请求

const pro = new Promise(function(resolve, reject) {
  $.ajax({
    type: "GET",
    url: "ajax.json",
    dataType: "json",
    success: function(data) {
      resolve(data);
    },
    failure: function(err) {
      reject(err);
    }
  });
});

pro.then((data) => {
  $('#box').html(`<li>name:${data.name}</li><li>age:${data.age}</li>`);
}).catch((err) => {
  console.log("error: ",err);
})

3. promise.all

Promise.all([ ]):当都成功时,才返回成功

let p1 = new Promise((res, rej)=>{
  setTimeout(() => {
    res("success-1");
  }, 1000);
});
let p2 = new Promise((res, rej)=>{
  setTimeout(() => {
    res("success-2");
  }, 1000);
});
let p3 = new Promise((res, rej)=>{
  setTimeout(() => {
    res("success-3");
  }, 1000);
});

let pro = Promise.all([p1,p2,p3]);
pro.then((data)=>{
  console.log(data);
}).catch(()=>{
  console.log("failure");
});

4. promise.race

promise.race:当其中一个有结果时,就返回结果

let p1 = new Promise((res, rej)=>{
  setTimeout(() => {
    res();
  }, 1000);
});
let p2 = new Promise((res, rej)=>{
  setTimeout(() => {
    rej();
  }, 500);
});
let p3 = new Promise((res, rej)=>{
  setTimeout(() => {
    res();
  }, 1000);
});

let pro = Promise.race([p1,p2,p3]);
pro.then(()=>{
  console.log("success");
}).catch(()=>{
  console.log("failure");
});

8. async

异步执行

await 同行的代码同步执行,后面的代码异步执行

// promise
const pro = new Promise((res, rej) => {
  setTimeout(() => {
    res("result data");
  }, 2000);
});
// async
async function asyncFunc() {
  let data = await pro;
  console.log("data:", data);
}
// 调用函数
asyncFunc();

9. class 类

1. 基础使用

  1. class 定义类,
class Point {
  _sex = "男";

  // 构造函数:属性
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  // 方法
  method () {
    if (this.name=="node") return this.age=20;
  }

  get sex() {
    return this._sex;
  }
  set sex(value) {
    this._sex = value;
    if (this._sex!='男' && this._sex!='女') {
      throw new Error("这不属于性别属性");
    }
  }
}

let poi = new Point("node", 18);
// 属性
console.log("name:",poi.name);
console.log("age:",poi.age);
// 方法
poi.method()
console.log("method:",poi.age);
// get
console.log("get:",poi.sex);
// set
poi.sex = "孩子";
console.log("set:",poi.sex);

10. 类:监听

  1. data:是自定义的一个属性
  2. get:使用 data 时,执行get里的内容
  3. set:当改变data时,执行set里的内容
class point {
  value = 10;
  get data(){
    console.log("value被使用了:",this.value);
  }
  set data(val){
    this.value = val;
    console.log("value被改变了",this.value);
  }
}

let p = new point();
p.data;
p.data = 20;
p.data;

11. 类:静态方法

  1. 使用 static 定义静态方法
  2. 静态方法只能使用类名调用,不能使用实例类名调用
class point {
  constructor(){
    this.name = "class";
    this.age = 20;
  }
  // 普通方法
  sayName(){
    console.log(this.name);
  }
  // 静态方法
  static sayAge(val){
    console.log(val);
  }
}

let p = new point();
p.sayName();
point.sayAge(20);

12. 类:继承

// 父类
class point {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  method() {
    console.log("my name is", this.name);
  }
}

// 子类
class student extends point {
  constructor(name, age, sex) {
    super(name, age);
    this.sex = sex;
  }
  method() {
    console.log("my name is", this.name);
    console.log("my sex is", this.sex);
  }
}

// 实例化子类
let s = new student("node", 18, "man");
console.log(s.name, s.age, s.sex);
s.method();

13. fs:文件操作模块

1. 基本使用

读取文件

// 加载模块
const fs = require('fs');
// 读取文件	--> 同步
let data = fs.readFileSync("file.txt");
console.log(data);
console.log(data.toString());
data = fs.readFileSync("file.txt", 'utf-8');
console.log(data);
// 读取文件 --> 异步
fs.readFile("file.txt", (err, data)=>{
  // 如果报错:抛出异常信息
  if (err) {
    throw err;
  }
  // 打印文件内容
  console.log(data); // 格式:buffer
  console.log(data.toString());
});

写入文件

const fs = require('fs');

// 读文件
fs.readFile('file.txt', (err, data)=>{
  if (err) throw err;
  // 内容
  let str = "";
  if (data.toString()=="") {
    str = "hello node"
  } else {
    str = data.toString()+"\n"+"hello node";
  }
  // 写文件
  fs.writeFile('file.txt', str, (err)=>{
    if (err) throw err;
  });
});

// 追加内容
fs.appendFile('file.txt', "hello world ", (err)=>{
  if (err) throw err;
  console.log("successful");
})

2. 文件夹

const fs = require('fs');

// 读文件夹
fs.readdir('test', (err, data)=>{
  if (err) throw err;
  console.log(data);
});

// 创建文件夹
fs.mkdir('test/test3', (err)=>{
  if (err) throw err;
  console.log("create successful");
});

// 删除文件夹
fs.rmdir('test/test1', (err)=>{
  if (err) throw err;
  console.log("remove successful");
});

3. 文件流

读入流

const fs = require('fs');

// 创建读取流
let readSteam = fs.createReadStream('read.txt');
// 开始读取
let str = "";
readSteam.on('data', (value)=>{
  str += value;
});
// 读取完成
readSteam.on('end', ()=>{
  console.log(str);
});
// 异常信息
readSteam.on('error', (err)=>{
  console.log(err);
});

写入流

const fs = require('fs');

// 创建写入流
let write = fs.createWriteStream('write.txt');
// 写入数据
let data = "hello,我是写入内容";
write.write(data, 'utf8');
// 写入结束
write.end();
// 写入完成
write.on('finish', ()=>{
  console.log("写入成功");
});
// 写入异常
write.on('error', (err)=>{
  console.log(err);
});

4. 管道流

read.pipe(write):对接一个读取流和写入流,然后会形成一个管道

const fs = require('fs');

// 创建读流和写流
let read = fs.createReadStream('read.txt');
let write = fs.createWriteStream('write.txt');
// 对接流
read.pipe(write);
// 写入完成
write.on('finish', ()=>{
  console.log("success");
});

5. 回调:删除文件及文件夹

const fs = require('fs').promises;

async function removeFile(path) {
  // 读取目录
  let dirArr = await fs.readdir(path);
  // 遍历
  for (value of dirArr) {
    let file = path+"/"+value;
    let temp = await fs.stat(file);
    if (temp.isFile()) {
      await fs.unlink(file);
      console.log("remove successfel ", file);
    } else {
      await removeFile(file);
    }
  }
  
  // 删除目录
  await fs.rmdir(path);
  console.log("remove successfel ", path);
}

var path = "test/test";
removeFile(path);

14. Event:事件监听模块

  1. event.on():事件监听
  2. event.emit():事件绑定(事件触发)
const { EventEmitter } = require('events');

// 初始化一个监听对象
var ev = new EventEmitter();
// 监听事件
ev.on(sayName, ()=>{
  console.log("事件监听中...");
})
// 触发事件
ev.emit(sayName);

function sayName(){
  console.log("say name");
}

15. HTTP:http请求模块

  1. requset:请求
  2. response:响应
  3. server.listen:监听端口
const http = require('http')

const server = http.createServer((requset, response)=>{
  res.end("result");
})

server.listen(8080, ()=>{
  console.log("8080 端口监听中");
})

16. URl:地址模块

const url = require('url').URL;

const urls = new URL('https://www.baidu.com:3000/');
urls.href		//url提交地址 (https://www.baidu.com/)
urls.host		//url路径地址 (www.baidu.com)
urls.hostname	//url路径地址 (www.baidu.com)
urls.origin		//url提交地址 (https://www.baidu.com/)
urls.username	//username
urls.password	//password
urls.port		//端口
urls.protocol	//协议 (https)
urls.search		//查询内容

17. querystring:模块

const query = require('querystring')

var path = "http://localhost:3000?id=001&name=node"
var str = query.parse(path)
console.log(str);

18. express:node框架

1. 安装,目录结构

npm i express-generator -g
express --view=ejs [name]
cnpm install
npm start
[name]
	- bin  //启动文件:端口
		www
	- public  //静态文件
		- img
		- js
		- css
	- routes  //路由
		index.js
		home.js
	- views  //页面:模板引擎
		error.ejs
		index.ejs
	app.js  //主文件
	package.json  //配置文件

2. router 路由

routes/index.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

app.js

var indexRouter = require('./routes/index');
app.use('/', indexRouter);

3. ejs:前端页面

<%= title%>:使用数据

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <ul>
    	<% for(var i=0; i<list.length; i++){ %>
        <li>name:<%= list[i] %></li>
        <% } %>
   	</ul>
  </body>
</html>

4. 中间件

app.use(function(req, res, next) {
  // 检测token值,如果成功,进入下一个中间件,失败发送错误
  if (req.query.token) {
    console.log(req.query.token);
    next("进入下一个中间件");
  } else {
    res.send("token无效");
  }
});

app.use(function(value, req, res, next) {
  console.log(value);
  console.log("接收上一个中间件的传值");
  next();
});

跨域

app.all('*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-type");
  res.header("Access-Control-Allow-Methods", "*");
  res.header('Content-Type', 'application/json;charset=utf-8');
  next();
});

19. mongoDB:数据库

1. 安装

npm i mongoose --save

2. 使用

mongoose/db.js

const mongoose = require('mongoose');
/*
  连接数据库的地址
  连接方式://服务器:端口号/数据库名称
*/
let url = "mongodb://localhost:27017/web";
	
// 连接数据库
mongoose.connect(url);
mongoose.connection.on('connected', ()=>{
  console.log("连接成功");
});
mongoose.connection.on('error', ()=>{
  console.log("连接失败");
});

module.exports = mongoose;

mongoose/product.js

const mongoose = require('./db.js');
// 表字段约束
const schema = new mongoose.Schema({
  name: {type:String},
  age: {type:Number},
  sex: {type:String},
  hobby: {type:String},
  state: {type:Number}
});
// 表跟与约束的映射
const model = mongoose.model('product', schema);

module.exports = model;

增删改查

const Model_Pro = require('../mongoose/product.js');
// 添加数据
router.post('/', (req, res)=>{
  var p = new Model_Pro({
    name: req.body.name,
    age: req.body.age,
    sex: req.body.sex,
    hobby: req.body.hobby,
    state: req.body.state
  });
  p.save((err, result)=>{
    if (err) {
      res.render('index', {message:"添加信息失败"});
    } else {
      res.render('index', {message:"添加信息完成"});
    }
  });
});
Model_Pro.find( {name:'node'} )					//查询
Model_Pro.update( {name:'node'},{state:true} )	//更新
Model_Pro.remove( {name:'node'} )				//删除

20. 第三方工具

热启动

npm i nodemon -g

npm install nodemon --save
nodemon start

页面图标 (中间件)

npm i serve-favicon --save
const favIcon = require('serve-favicon')
app.use(favIcon(path.json(__dirname, 'public', 'favicon.ico')))

生成验证码

npm i svg-captcha --save
const svg = require('svg-captcha')
router.get('/svg', (req, res)=>{
    var captcha = svg.create();
})
<object data="captcha/svg" type="image/svg+xml"></object>

21. webSocket 双向通信

const WebSocket = require('ws');
const server = new WebSocket.Server({port:8080});

// 数据  成员
let User={}, UserArr=[];
// 发送
server.on('connection', function connection(ws) {
  UserArr.push(ws);

  // 接收
  ws.on('message', function incoming(message) {
    User = JSON.parse(message);

    if (User.data!=undefined) {
      for (item of UserArr) {
        // 内容
        item.send(`${User.name}${User.data}`);
      }
    } else {
      ws.send(`${User.name} -- 已上线`);
    }
  });  
});

22. 模块化

1. CommonJS

  1. module.exports={ } 导出方法
  2. require(./module.js) 引入方法
  3. 一般在 node 包引用的时候使用
// module.js
let i = {
  name: "node",
  info: "基于 Chrome V8 引擎 的 JavaScript"
}
function name() {	// 打印名字
  console.log(i.name);
}
function info() {	// 打印信息
  console.log(i.info);
}
// 输出模块
module.exports = {
  name,
  info
};
// index.js
// 加载模块
const mod = require("./自定义模块.js");

// 调用方法
mod.name();
mod.info();

2. ES6

  1. import:引入外部模块
  2. export:导出属性和方法,可以同时导出多个
  3. export default:导出属性和方法,只能导出一个
// module.js
let i = {
  name: "node",
  info: "基于 Chrome V8 引擎 的 JavaScript"
}
function sayName() {	// 打印名字
  console.log(i.name);
}
function sayInfo() {	// 打印信息
  console.log(i.info);
}
// 输出模块
export {
  sayName,
  sayInfo
};
// index.js
// 加载模块
import {sayName,sayInfo} from './module'

// 调用方法
sayName();
sayInfo();

23. 获取表单上传内容

multiparty

1. 安装

npm install multiparty --save

24. mysql数据库