复习:
1、Mysql数据库:关系型数据库。用二维表来保存数据
(1)主键:用来唯一标识表中一个记录。取值必须唯一、不能为空。只有在MySQL数据库中主键为int型时才会自增
(2)字符串类型:varchar、char
2、先有数据库,在数据库中包含若干数据表。SQL(结构化查询语言)是关系型数据库的通用查询语言
3、Node通过Sequelize模块来访问关系型数据库:ORM映射
模型名 <————————> 表名
属性名 <————————> 列名
对象名 <————————> 记录
映射的好处:在Node程序中操作模型、对象,就是操作数据表、表中的记录
1、增加记录:insert into 表名(列名1,列名2,列名3,……) values(值1,值2,值3,……)
模型名.create({}).then((result)=>{
保存成功后的回调
}).catch((err)=>{
操作出现异常的处理代码
})
- //插入记录接口:http://localhost:9001/bookapi/addBook
- router.post('/addBook',(req,res)=>{
- Book.create({
- isbn: req.body.book_isbn,
- name: req.body.book_name,
- author: req.body.book_author,
- press: req.body.book_publish,
- price: req.body.book_price,
- pubdate: req.body.publish_date
- }).then((result) => {
- if (result) {
- res.json({
- code: 1002
- })
- }
- }).catch (e=>{
- console.log(e)
- })
- })
、删除记录:delete from 表名 [ where 条件 ]
模型名.destroy({
where: {
列名: 值
}
}).then((result)=>{
删除成功后的回调
}).catch((err)=>{
操作出现异常的处理代码
})
delete方式请求:接收客户端数据时采用的是 req.body.参数名 的方式
- //删除记录接口:http://localhost:9001/bookapi/delBook
- router.delete('/delBook',(req,res)=>{
- let bid = req.body.id //接收客户发送的id
- //删除记录
- Book.destroy({ //'delete from bookinfo where id ='+ bid
- where: {
- id: bid
- }
- }).then((result)=>{ //result中保存的是删除的记录数
- res.json({
- code:2000,
- msg:result
- })
- }).catch((e)=>{
- console.log(e)
- res.json({
- code: 1000,
- msg: '删除失败'
- })
- })
- })
3、更新记录:update 表名 set 列名1=值1,…… [ where 条件 ]
模型名.update({ 修改的列 },{ where 条件 }).then((result)=>{
更新成功后的回调
}).catch((e)=>{
出现异常的回调
})
put方式:后台接收参数的方式 req.body.参数名
- // 更新记录接口:http://localhost:9001/bookapi/updateBook
- router.put('/updateBook',(req,res)=>{
- //1.先获取所有字段的值
- let { bid,bisbn,bname,bauthor,bpress,bprice,bpubdate} = req.body
- console.log(bid,bname)
- //2.更新满足条件的记录
- Book.update({
- isbn: bisbn,
- name: bname,
- author: bauthor,
- press: bpress,
- price: bprice,
- pubdate: bpubdate
- },{
- where:{
- id: bid
- }
- }).then((result)=>{
- res.json({
- code: result
- })
- }).catch((e)=>{
- console.log(e)
- })
- })
4、查询记录
(1)查询所有记录:
模型名.findAll().then((result)=>{ //result:是一个数组,存放的是从数据库中查询到的所有记录
查询成功后的回调
}).catch((e)=>{
执行查询出现异常的回调
})
- // 查询所有接口:http://localhost:9001/bookapi/findAll
- router.get('/findAll',(req,res)=>{
- Book.findAll().then((result)=>{ //result存放的是从数据库中查询到的数据
- res.json(JSON.stringify(result))
- })
- })
强调:在执行带条件查询时需要导入Sequelize模块中的Op子模块,在Op子模块中有条件查询的关键字
(2)模糊查询:
- const Op = require(‘sequelize’).Op
- //模糊查询(按作者姓氏查询):http://localhost:9001/bookapi/findLike
- router.post(‘/findLike’,(req,res)=>{
- //1.获取前端发送的作者的姓氏
- let firstName = req.body.firstname
- //2.进行模糊查询
- Book.findAll({
- where:{
- author: {
-
- [Op.like]: firstName+'%'
- }
- }
- }).then((data)=>{
- res.json(data)
- }).catch(e=>{
- console.log(e)
- res.json('查询失败')
- })
- })
-
- ```
(3)按id查询:
- //按id查询:http://localhost:9001/bookapi/findById
- router.post('/findById',(req,res)=>{
- //1.获取客户端发送的id
- let bid = req.body.bookId
- //2.进行查询
- Book.findOne({
- where:{
- id: bid
- }
- }).then((data)=>{
- res.json(data)
- }).catch(e=>{
- console.log(e)
- res.json('查询失败')
- })
- })
二、回调地狱
1、回调函数:把一个函数作为参数传递给另一个函数,在另一个函数中作为参数的函数不会立即执行,只有当满足某个条件后才会执
2、同步任务:主线程任务队列中的程序依次执行,只有当前一个任务执行结束后才会执行后一个任务
3、异步任务:不会进入主主线程队列,它会进入异步的队列。前一个任务是否执行完毕不影响下一个任务的执行
- console.log('第一个任务')
- setTimeout(function(){
- console.log('第二个任务') //异步任务
- },0)
- console.log('第三个任务')
异步任务又称为不阻塞任务:前一个任务的执行不阻塞后一个任务的执行
(1)可读性差,维护困难
(2)无法进行return和throw
(3)多个回调之间无法建立联系
三、Promise对象:是一个原生的js对象,为了解决回调地狱问题,可以替换掉回调函数。是一个新的异步任
(1)pending[待定] 初始状态
(2)resloved[实现] 操作成功
(3)rejected[被否决] 操作失败
(1)当promise对象的状态发生改变时就会触发后面的.then()的响应函数来执行后续的操作
(2)状态一经改变就不会再变
(3)promist对象一经创建就会立即执行 —- 异步任务的同步效果
强调:promise为什么能连续的.then —->因为.then里面的回调函数的返回值也是一个promist对象
Promise(function(resolve,reject){ })
resolve:表示异步操作成功后的回调函数,将promise对象的状态由初始状态转换到成功状态,并将回调函数的执行结果传
递出去,由下一个then来接收……
reject:表示异步操作失败后的回调函数,在回调函数执行错误时调用,并将错误的信息作为参数传递出去,由catch来接收…
- function fn(str){ //返回值是一个Promise对象
- //创建Promise对象
- let p =new Promise((resolve,reject)=>{
- var flag = true
- if(flag){
- resolve(str)
- }else{
- reject('操作失败')
- }
- })
- return p
- }
- fn('武林要以和为贵').then((data)=>{
- console.log(data)
- return fn('要讲武德') //返回一个Promise对象
- }).then((data)=>{
- console.log(data)
- return fn('不要搞窝里斗') //返回一个Promise对象
- }).then((data)=>{
- console.log(data)
- }).catch((e)=>{
- console.log(e)
- })
4、Promise的all方法:实现了异步任务的并行执行能力
- function getWidth(){ //返回Promise对象
- return new Promise((resolve,reject)=>{
- setTimeout(resolve(5),3000)
- })
- }
- function getHeight(){//返回Promise对象
- return new Promise((resolve,reject)=>{
- setTimeout(resolve(4),1000)
- })
- }
- Promise.all([getWidth(),getHeight()]).then((result)=>{ //调用两个异步函数,实现并行运行
- console.log('结果:',result)
- })
四、async函数和await函数:ES7出现的
1、Promise对象的缺陷:虽然跳出了回调地狱,但是在流程复杂的代码中会出现很多的then,这样导致代码的可读性也很差
2、async/await出现的原因:是对Promise的一种优化,又称为Promise的语法糖
- var sleep = function(time){
- return new Promise((resolve,reject)=>{
- setTimeout(function(){
- resolve('######')
- },time)
- })
- }
- var start = async function(){ //异步调用,实现同步效果
- console.log('start')
- await sleep(3000).then((data)=>{
- console.log(data)
- })
- console.log('end')
- }
- start()
3、async/await的使用规则
(1)await关键字只能在async标识的函数中使用
(2)await后面可以直接跟一个 Promise对象(更多的是跟一个返回Promise对象的表达式)
(3)await函数不能单独使用
(4)await可以直接拿到Promise中resolve中的数据。
- function fn(str){ //返回值是一个Promise对象
- //创建Promise对象
- let p =new Promise((resolve,reject)=>{
- var flag = true
- if(flag){
- resolve(str)
- }else{
- reject('操作失败')
- }
- })
- return p
- }
- async function test(){
- let r1 = await fn('武林要以和为贵')
- let r2 = await fn('要讲武德')
- let r3 = await fn('不要搞窝里斗')
- console.log(r1)
- console.log(r2)
- console.log(r3)
- }
- test()
4、promise和async/await区别
(1)promise是ES6中出现,async/await是在ES7中出现
(2)async/await的写法更优雅
(3)对reject状态的捕捉方式不同
a、promise采用.then后面跟.catch方法捕捉,通常.catch放在最后
b、async/await可以用.then后面跟.catch方法捕捉,也可以使用try…catch方式捕捉