一、CRUD接口的实现
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)
})
})
2. 删除记录:delete from 表名 [ where 条件 ]
模型名.destroy({
where: {
列名: 值
}
}).then((result)=>{
删除成功后的回调
}).catch((err)=>{
操作出现异常的处理代码
})
delete方式请求:接收客户端数据时采用的是 req.query.参数名 的方式
//删除记录接口: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//导入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('第三个任务')
异步任务又称为不阻塞任务:前一个任务的执行不阻塞后一个任务的执行
setTimeout(function(){
console.log('第1个任务')
setTimeout(function(){
console.log('第2个任务')
setTimeout(function(){
console.log('第3个任务') //异步任务
},1000) //异步任务
},2000) //异步任务
},3000)
5. 回调地狱的缺点
(1)可读性差,维护困难
(2)无法进行return和throw
(3)多个回调之间无法建立联系
三、Promise对象
Promise对象是一个原生的js对象,为了解决回调地狱问题,可以替换掉回调函数。是一个新的异步任务的解决方案。
它通过引入一个回调,避免更多的回调.
Promise的字面意思是“承诺”,即承诺会执行。简单说Promise就是一个容器,里面保存着某个未来才会执行完毕的事件(通常是一个异步操作)的结果,而这些结果一旦生成是无法改变的。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。
(1)pending[待定] 初始状态
(2)resloved[实现] 操作成功
(3)rejected[被否决] 操作失败
2. 执行过程
(1)当promise对象的状态发生改变时就会触发后面的.then()的响应函数来执行后续的操作
(2)promise的状态值只能从pending -> fulfilled 或者 pending -> reject,状态一旦确定就不会再改变
(3)promist对象一经创建,执行器就会立即执行 —- 异步任务的同步效果
new Promise调用的时候需要传入一个executor执行器函数,该函数会立即执行;
(4)executor函数接收两个参数,resolve,reject,分别对应异步请求成功执行和失败执行;
(5)设置默认状态stratus为pending,请求成功状态下的值为value,默认值为undefined,请求失败下的值为reason,默认值为unfined
强调:promise为什么能连续地.then —->因为.then里面的回调函数的返回值也是一个promist对象
Promise(function(resolve,reject){ })
resolve:表示异步操作成功后的回调函数,将promise对象的状态由初始状态转换到成功状态,并将回调函数的执行结果传递出去,由下一个then来接收……
reject:表示异步操作失败后的回调函数,在回调函数执行错误时调用,并将错误的信息作为参数传递出去,由catch来接收…
Promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败时相应的数据
Promise的链式编程可以保证代码的执行顺序,前提是每一次在then做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据
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的语法糖
async和await遵循的是Generator 函数的语法糖,他拥有内置执行器,不需要额外的调用直接会自动执行并输出结果,它返回的是一个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函数不能单独使用,await关键字只能在async标识的函数中使用
(2)await后面可以直接跟一个Promise对象(更多的是跟一个返回Promise对象的表达式)
(3)返回值是promise对象
(4)await可以直接拿到Promise中resolve中的数据。
(5)在使用异步的操作前+await,函数前写async关键字。
(6)出现了await关键字之后的代码都要在其执行之后才会执行。
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状态的捕捉方式不同
- promise采用.then后面跟.catch方法捕捉,通常.catch放在最后
- async/await可以用.then后面跟.catch方法捕捉,也可以使用try…catch方式捕捉
五、使用async/await对CRUD进行封装
1. 定义dao层:数据库访问层。专门用于访问数据库,不和接口直接联系
2. 定义service层:服务层。通过调用dao层的方法来获取数据,将结果通过res对象响应给客户端
4. 案例:模型的创建—->dao层定义—->service层定义—->路由文件的定义
模型:
(1)定义dao层:DataBase Option —- 数据库访问层(操作数据库)
a、定义模型:实现ORM映射。course(cid,cname,cgrade)
b、定义操作:通过模型对数据库进行访问
(2)定义服务层:
a、与客户端进行交互
b、通过dao层访问数据库
(3)接口:根据客户的请求路径,路由的对应的服务
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/79759.html