• Promise对象和async/await


    复习:

    1、Mysql数据库:关系型数据库。用二维表来保存数据

    ​ (1)主键:用来唯一标识表中一个记录。取值必须唯一、不能为空。只有在MySQL数据库中主键为int型时才会自增

    ​ (2)字符串类型:varchar、char

    2、先有数据库,在数据库中包含若干数据表。SQL(结构化查询语言)是关系型数据库的通用查询语言

    3、Node通过Sequelize模块来访问关系型数据库:ORM映射

    ​ 模型名 <————————> 表名

    ​ 属性名 <————————> 列名

    ​ 对象名 <————————> 记录

    映射的好处:在Node程序中操作模型、对象,就是操作数据表、表中的记录

    一、CRUD接口的实现

    1、增加记录:insert into 表名(列名1,列名2,列名3,……) values(值1,值2,值3,……)

    ​ 模型名.create({}).then((result)=>{

    ​ 保存成功后的回调

    ​ }).catch((err)=>{

    ​ 操作出现异常的处理代码

    ​ })

    1. //插入记录接口:http://localhost:9001/bookapi/addBook
    2. router.post('/addBook',(req,res)=>{
    3. Book.create({
    4. isbn: req.body.book_isbn,
    5. name: req.body.book_name,
    6. author: req.body.book_author,
    7. press: req.body.book_publish,
    8. price: req.body.book_price,
    9. pubdate: req.body.publish_date
    10. }).then((result) => {
    11. if (result) {
    12. res.json({
    13. code: 1002
    14. })
    15. }
    16. }).catch (e=>{
    17. console.log(e)
    18. })
    19. })

    、删除记录:delete from 表名 [ where 条件 ]

    ​ 模型名.destroy({

    ​ where: {

    ​ 列名: 值

    ​ }

    ​ }).then((result)=>{

    ​ 删除成功后的回调

    ​ }).catch((err)=>{

    ​ 操作出现异常的处理代码

    ​ })

    delete方式请求:接收客户端数据时采用的是 req.body.参数名 的方式

    1. //删除记录接口:http://localhost:9001/bookapi/delBook
    2. router.delete('/delBook',(req,res)=>{
    3. let bid = req.body.id //接收客户发送的id
    4. //删除记录
    5. Book.destroy({ //'delete from bookinfo where id ='+ bid
    6. where: {
    7. id: bid
    8. }
    9. }).then((result)=>{ //result中保存的是删除的记录数
    10. res.json({
    11. code:2000,
    12. msg:result
    13. })
    14. }).catch((e)=>{
    15. console.log(e)
    16. res.json({
    17. code: 1000,
    18. msg: '删除失败'
    19. })
    20. })
    21. })

    3、更新记录:update 表名 set 列名1=值1,…… [ where 条件 ]

    ​ 模型名.update({ 修改的列 },{ where 条件 }).then((result)=>{

    ​ 更新成功后的回调

    ​ }).catch((e)=>{

    ​ 出现异常的回调

    ​ })

    put方式:后台接收参数的方式 req.body.参数名

    1. // 更新记录接口:http://localhost:9001/bookapi/updateBook
    2. router.put('/updateBook',(req,res)=>{
    3. //1.先获取所有字段的值
    4. let { bid,bisbn,bname,bauthor,bpress,bprice,bpubdate} = req.body
    5. console.log(bid,bname)
    6. //2.更新满足条件的记录
    7. Book.update({
    8. isbn: bisbn,
    9. name: bname,
    10. author: bauthor,
    11. press: bpress,
    12. price: bprice,
    13. pubdate: bpubdate
    14. },{
    15. where:{
    16. id: bid
    17. }
    18. }).then((result)=>{
    19. res.json({
    20. code: result
    21. })
    22. }).catch((e)=>{
    23. console.log(e)
    24. })
    25. })

    4、查询记录

    ​ (1)查询所有记录:

    ​ 模型名.findAll().then((result)=>{ //result:是一个数组,存放的是从数据库中查询到的所有记录

    ​ 查询成功后的回调

    ​ }).catch((e)=>{

    ​ 执行查询出现异常的回调

    ​ })

    1. // 查询所有接口:http://localhost:9001/bookapi/findAll
    2. router.get('/findAll',(req,res)=>{
    3. Book.findAll().then((result)=>{ //result存放的是从数据库中查询到的数据
    4. res.json(JSON.stringify(result))
    5. })
    6. })

    强调:在执行带条件查询时需要导入Sequelize模块中的Op子模块,在Op子模块中有条件查询的关键字

    ​ (2)模糊查询:

    1. const Op = require(‘sequelize’).Op
    2. //模糊查询(按作者姓氏查询):http://localhost:9001/bookapi/findLike
    3. router.post(‘/findLike’,(req,res)=>{
    4. //1.获取前端发送的作者的姓氏
    5. let firstName = req.body.firstname
    6. //2.进行模糊查询
    7. Book.findAll({
    8. where:{
    9. author: {
    10. [Op.like]: firstName+'%'
    11. }
    12. }
    13. }).then((data)=>{
    14. res.json(data)
    15. }).catch(e=>{
    16. console.log(e)
    17. res.json('查询失败')
    18. })
    19. })
    20. ```

    (3)按id查询:

    1. //按id查询:http://localhost:9001/bookapi/findById
    2. router.post('/findById',(req,res)=>{
    3. //1.获取客户端发送的id
    4. let bid = req.body.bookId
    5. //2.进行查询
    6. Book.findOne({
    7. where:{
    8. id: bid
    9. }
    10. }).then((data)=>{
    11. res.json(data)
    12. }).catch(e=>{
    13. console.log(e)
    14. res.json('查询失败')
    15. })
    16. })

    二、回调地狱

    1、回调函数:把一个函数作为参数传递给另一个函数,在另一个函数中作为参数的函数不会立即执行,只有当满足某个条件后才会执

    行,这个函数称为回调函数。

    2、同步任务:主线程任务队列中的程序依次执行,只有当前一个任务执行结束后才会执行后一个任务

    3、异步任务:不会进入主主线程队列,它会进入异步的队列。前一个任务是否执行完毕不影响下一个任务的执行

    1. console.log('第一个任务')
    2. setTimeout(function(){
    3. console.log('第二个任务') //异步任务
    4. },0)
    5. console.log('第三个任务')

    异步任务又称为不阻塞任务:前一个任务的执行不阻塞后一个任务的执行

    4、什么是回调地狱:回调函数嵌套回调函数就会形成回调地狱

    5、回调地狱的缺点:

    ​ (1)可读性差,维护困难

    ​ (2)无法进行return和throw

    ​ (3)多个回调之间无法建立联系

    三、Promise对象:是一个原生的js对象,为了解决回调地狱问题,可以替换掉回调函数。是一个新的异步任

    务的解决方案。

    1、promise的三种状态

    ​ (1)pending[待定] 初始状态

    ​ (2)resloved[实现] 操作成功

    ​ (3)rejected[被否决] 操作失败

    2、执行过程:

    ​ (1)当promise对象的状态发生改变时就会触发后面的.then()的响应函数来执行后续的操作

    ​ (2)状态一经改变就不会再变

    ​ (3)promist对象一经创建就会立即执行 —- 异步任务的同步效果

    强调:promise为什么能连续的.then —->因为.then里面的回调函数的返回值也是一个promist对象

    3、构造函数

    ​ Promise(function(resolve,reject){ })

    ​ resolve:表示异步操作成功后的回调函数,将promise对象的状态由初始状态转换到成功状态,并将回调函数的执行结果传

    递出去,由下一个then来接收……

    ​ reject:表示异步操作失败后的回调函数,在回调函数执行错误时调用,并将错误的信息作为参数传递出去,由catch来接收…

    1. function fn(str){ //返回值是一个Promise对象
    2. //创建Promise对象
    3. let p =new Promise((resolve,reject)=>{
    4. var flag = true
    5. if(flag){
    6. resolve(str)
    7. }else{
    8. reject('操作失败')
    9. }
    10. })
    11. return p
    12. }
    13. fn('武林要以和为贵').then((data)=>{
    14. console.log(data)
    15. return fn('要讲武德') //返回一个Promise对象
    16. }).then((data)=>{
    17. console.log(data)
    18. return fn('不要搞窝里斗') //返回一个Promise对象
    19. }).then((data)=>{
    20. console.log(data)
    21. }).catch((e)=>{
    22. console.log(e)
    23. })

    4、Promise的all方法:实现了异步任务的并行执行能力

    1. function getWidth(){ //返回Promise对象
    2. return new Promise((resolve,reject)=>{
    3. setTimeout(resolve(5),3000)
    4. })
    5. }
    6. function getHeight(){//返回Promise对象
    7. return new Promise((resolve,reject)=>{
    8. setTimeout(resolve(4),1000)
    9. })
    10. }
    11. Promise.all([getWidth(),getHeight()]).then((result)=>{ //调用两个异步函数,实现并行运行
    12. console.log('结果:',result)
    13. })

    四、async函数和await函数:ES7出现的

    1、Promise对象的缺陷:虽然跳出了回调地狱,但是在流程复杂的代码中会出现很多的then,这样导致代码的可读性也很差

    2、async/await出现的原因:是对Promise的一种优化,又称为Promise的语法糖

    1. var sleep = function(time){
    2. return new Promise((resolve,reject)=>{
    3. setTimeout(function(){
    4. resolve('######')
    5. },time)
    6. })
    7. }
    8. var start = async function(){ //异步调用,实现同步效果
    9. console.log('start')
    10. await sleep(3000).then((data)=>{
    11. console.log(data)
    12. })
    13. console.log('end')
    14. }
    15. start()

    3、async/await的使用规则

    ​ (1)await关键字只能在async标识的函数中使用

    ​ (2)await后面可以直接跟一个 Promise对象(更多的是跟一个返回Promise对象的表达式)

    ​ (3)await函数不能单独使用

    ​ (4)await可以直接拿到Promise中resolve中的数据。

    1. function fn(str){ //返回值是一个Promise对象
    2. //创建Promise对象
    3. let p =new Promise((resolve,reject)=>{
    4. var flag = true
    5. if(flag){
    6. resolve(str)
    7. }else{
    8. reject('操作失败')
    9. }
    10. })
    11. return p
    12. }
    13. async function test(){
    14. let r1 = await fn('武林要以和为贵')
    15. let r2 = await fn('要讲武德')
    16. let r3 = await fn('不要搞窝里斗')
    17. console.log(r1)
    18. console.log(r2)
    19. console.log(r3)
    20. }
    21. 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方式捕捉

  • 相关阅读:
    微服务项目:尚融宝(13)(前端平台:搭建管理平台前端程序)
    altera FPGA 程序固化命令
    LATR:3D Lane Detection from Monocular Images with Transformer
    输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;
    iostat 命令详解
    Windows Server 2012 R2系统 修改远程登陆密码
    MFC Windows 程序设计[333]之高亮列表控件(附源码)
    图解八股,真的太顶了
    车载双向认证框架设计
    npm包、全局数据共享、分包
  • 原文地址:https://blog.csdn.net/m0_74331185/article/details/128085071