ES6基础
ES6模块化规范
1、每个js文件都是一个独立的模块
2、导入其他模块成员使用import关键字
3、向外共享模块成员使用export关键字
-------------------------------------------------------------------------
基于node.js体验ES6模块化
v14.15.1更高版本的node.js
在package.json根节点中添加"type":"module"节点
ES6模块化的基本语法
1、默认导出与默认导入
语法 | 注 |
export default {默认导出的成员} | 每个模块中只能默认导出一次 |
import 接收名称 from '模块标识符' | 接收名称任意即可 |
2、按需导出与按需导入
语法 | 注 |
export 按需导出的成员 | 可多次 |
import {s1, s2 as str2} from '模块标识符' | 成员必须包含在花括号中,可as重命名 |
注:
- 按需导入的成员名称必须与按需导出的成员名称一致
- 可以和默认导入一起使用
3、直接导入并执行模块中的代码
语法:import 要导入并执行的模块路径
Promise
链式调用解决回调地狱问题
构造函数
创建Promise实例 const p = new Promise()
new 出来的Promise对象,代表一个异步操作
Promise.prototype上包含一个.then()方法
.then()方法用来预先指定成功和失败的回调函数
p.then(成功的回调函数(箭头函数),失败的回调函数) 成功的回调函数是必选的
-------------------------------------------------------------------------
基于回调函数按顺序读取文件内容
1、安装then-fs
npm install then-fs
2、调用then-fs提供的readFile()方法,异步读取文件内容,返回值是Promise的实例对象
所以可以调用.then()
如果.then()返回的也是一个Promise回调函数则可以再调.then()
-------------------------------------------------------------------------
通过.catch捕获错误
在Promise的链式操作中如果发生了错误,可以使用Promise.prototype.catch方法进行捕获处理
-------------------------------------------------------------------------
Promise.all()等待机制
会发起并行的Promise异步操作,等所有的异步操作全部结束后才会执行下一步的.then()
const pro =[异步操作1,异步操作2,异步操作3,
]
//异步操作中的顺序就是数组中的顺序
Promise.all(pro).then(([r1, r2, r3]) => {console.log(r1, r2, r3)//1,2,3}).catch(err => {console.log(err.message)})
Promise.race()赛跑机制
会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行下一个.then()
const pro =[异步操作1,异步操作2,异步操作3,
]
//异步操作中的顺序就是数组中的顺序
Promise.race(pro).then(result => {console.log(result)//1}).catch(err => {console.log(err.message)})
-------------------------------------------------------------------------
基于Promise封装读文件的方法
方法的返回值为Promise实例对象
function getFile(fpath){return new Promise()//这里知识创建了一个形式上的异步操作
}
//如果想要创建具体的异步操作,则需要在new Promise()构造函数期间,传递一个function函数,将具体的异步操作定义到function函数内部
import fs from 'fs'function getFile(fpath){return new Promise(function(){fs.readFile(fpath,'utf8',(err,dataStr) => {})})//这里知识创建了一个形式上的异步操作
}
-------------------------------------------------------------------------
获取.then()的两个实参
通过.then()指定的成果和失败的回调函数,可以在function的形参中进行接收
import fs from 'fs'function getFile(fpath){return new Promise(function(resolve, reject){fs.readFile(fpath,'utf8',(err,dataStr) => {if(err) return reject(err)resolve(dataStr)})})//这里只是创建了一个形式上的异步操作
}// getFile('./files/1.txt').then (成功的回调函数,失败的回调函数)
getFile('./files/1.txt').then ( (r1) => {console.log(r1)},(err) => {console.log(err.message)})
-------------------------------------------------------------------------
async await
ES8引入的新语法,用来简化Promise异步操作
如果某个方法的返回值是一个Promise实例对象,前面就可以用await进行修饰,返回值就会变成一个真正的值
不用再通过.then的方式拿结果了
注意事项
- 用await必须写async
- 在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行
-------------------------------------------------------------------------
EventLoop(事件循环)
JS:单线程执行的编程语言(同一时间只能做一件事)
JS主线程从“任务队列”中读取异步任务的回调函数,放到执行栈中依次执行,这个过程循环不断
js单线程语言,容易导致程序假死问题(前一个任务非常耗时导致后续任务等待)
同步任务:非耗时任务,在js主线程上排队执行
异步任务:耗时任务,由js委托给宿主环境进行执行,执行完成后会通知JS主线程执行异步任务的回调函数
-------------------------------------------------------------------------
宏任务和微任务
异步任务分为宏任务和微任务
宏任务:异步Ajax请求、setTimeOut setInterval、文件操作、其他宏任务
微任务:Promise.then .catch .finally 、process.nextTick 、其他微任务
执行顺序
执行同步任务->执行所有微任务->执行宏任务->执行所有微任务->执行下一个宏任务
-------------------------------------------------------------------------
API接口案例
依赖第三方包express mysql2
实现步骤:
1、搭建项目基本结构
启用ES6模块支持 package.json中声明"type":"module"
安装第三方依赖包
运行
npm install express@4.17.1 mysql2@2.2.5
创建包管理配置文件
npm iniy -y
package.json中声明
"type":"module"//启用ES6模块化支持
装包:
npm i express@4.17.1 mysql2@2.2.5
2、创建express服务器
创建app.js
在app.js中写下面的代码
import express from "express";
const app = express();
// 启动服务器,运行在80端口
app.listen(80, () => {console.log("server running at http");
});
终端nodemon app.js运行
3、创建db数据操作模块
项目根目录创建db文件夹
文件夹中创建index.js文件
import mysql from "mysql2"//创建数据库连接对象
const pool = mysql.createPool({host:'127.0.0.1',port:'3306',database:'my_db_01',user:'root',password:'123456'
})export default pool.promise()
4、创建user_ctrl业务模块
调用db.query方法执行sql语句
项目根目录创建controller文件夹
文件夹中创建user_ctrl.js文件
import db from '../db/index.js'//使用ES6按需导出,将getAllUser方法导出供外界使用
export async function getAllUser (req,res){//返回值是promise可以用await优化const [rows]= await db.query("selsct id, username from ev_users")console.log(rows);//[{},{}]//将查询到的结果发送给后端res.send({status:0, //0成功1失败message:'获取用户列表数据成功',data:rows,})}
5、创建user_router路由模块
项目根目录创建router文件夹
文件夹中创建user_router.js文件
import express from 'experss'
import {getAllUser} from '../controller/user_ctrl'//创建路由对象
const router = new expess.Router()//监听客户端的get请求
router.get('/user',getAllUser)
export default router在app.js入口文件中挂载
//导入路由模块
import userRouter from './router/user_router'
//挂载
app.use('/api',userRouter)
-------------------------------------------------------------------------
使用try catch 捕获异常
try{
可能产生错误的代码的代码
}catch(e){
处理错误
}
try {//返回值是promise可以用await优化const [rows] = await db.query("selsct id, username from ev_users");console.log(rows); //[{},{}]//将查询到的结果发送给后端res.send({status: 0, //0成功1失败message: "获取用户列表数据成功",data: rows,});} catch (e) {res.send({status: 1, //0成功1失败message: "获取用户列表数据失败",desc: e.message,});}