promise

本文详细介绍了如何在Node.js环境中使用MySQL模块进行数据库操作,包括安装、连接、SQL查询、插入、更新和删除数据。同时,讨论了异步编程的回调函数、Promise和async/await的使用,以及如何通过Promise封装数据库操作,避免回调地狱,提升代码可读性和维护性。

Node操作Mysql

Mysql包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRLvMIU3-1635505573078)(img/4-12node操作mysql.png)]

下载mysql模块

npm i mysql	

在后端js文件中引入mysql

const mysql = require('mysql')

先创建mysql数据库的配置连接

let connectObj = mysql.createConnection({
				host:'主机名',
				user:'用户名',
				password:'密码'
				port:'端口号',
				database:'要操作哪个数据库'
			})

使用connectObj.query

connectObj.query(sqlStr,(err,results)=>{  })

流程

  • 下载mysql模块 npm i mysql
  • 引入mysql
  • 创建连接(登录数据库)
  • 书写sql语句 是以整个字符串形式来进行定义的,注意符合sql语法
  • 使用连接对象上的query方法执行sql语句
const mysql = require('mysql')

const connObj = mysql.createConnection( {
    host:'localhost',//127.0.0.1
    user:'root',
    password:'root',
    port:3306,
    database:'web803'
} ) //创建连接的函数   会返回一个数据库的连接对象

let sql1 = `INSERT INTO student ( idcard,username,age,sex,pro,tidcard,grade ) VALUES ( '30303','李四23',16,2,'北京','t2003','本科' )`

// connObj.query( sql,callbak ) //注意query是回调的语法,没有async写法,需自己封装 。
        //select update delete insert 被query执行以后有结果(前提err为null的时候)
connObj.query( sql1,(err,results)=>{
    console.log( err,'err' )
    console.log( results,'我是结果' )
} )
insert 操作
  • affectedRows: 影响了几行

  • insertId:新加的这条数据的id为xx

select操作
//回调的第2个参数永远是个数组。
// let sql = `SELECT * FROM student`
// let sql = `SELECT * FROM student WHERE id=2`
let sql = `SELECT * FROM student WHERE id=222`
// connOBj.query( sql,callback )  //sql:合格的sql语句, callback是个回调函数 

connOBj.query( sql,( err,result )=>{
    console.log( err,'错误信息' )
    console.log( result,'查到的结果' ) 
} )
update操作
let sql = `UPDATE student SET age=18 WHERE id=3`

connOBj.query( sql,( err,result )=>{
    // console.log( err,'错误信息' )
     console.log( result,'更新的结果' )  //affectedRows即可。受影响了几行

    if( !err && result.affectedRows > 0 ){
        console.log('成功')
    }else{
        console.log('更新失败')
    }

} )
delete操作
let sql = `DELETE FROM student WHERE id=8`

connOBj.query( sql,( err,result )=>{
    // console.log( err,'错误信息' )
     console.log( result,'删除的结果' )  //affectedRows即可。受影响了几行

    if( !err && result.affectedRows > 0 ){

        console.log('删除成功')
        return
    }else{
        console.log('删除失败')
        return
    }

} )

promise与异步与回调

Promise是ES6中语法层面上的知识点。

简介

Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理。

之前讲过两种编程方式:

1、 等号赋值。同步方法 。

2、回调函数|事件函数。异步方法。

回调函数和异步和同步

回调函数和异步同步关系

  • 回调可以是同步也可以是异步但node中回调风格都为异步

  • 异步必须放在回调里执行

  • 回调函数是为了在异步调用后接处理,即代码从上向下执行同步任务,遇到异步会跳过,如果我们想要拿到异步任务里的值继续在同步中处理就需要用到回调。

同步

js的特点:同步的(阻塞代码)

代码演示:(1)使用alert介绍同步阻塞(2)使用函数计算两个数的和调用后用变量接收

 // 同步的(阻塞代码)
// console.log(11)
// alert(3)
// console.log(222)

//同步函数的特点:可以等号赋值接收返回值,一行一行的往下运行

function computedSum( a,b ){

    a = a*10

    return a + b
}

let s1 = computedSum( 10,20 )
console.log( s1,'同步的特点' )

异步

js 是同步,代码很繁忙就会阻塞 。这就是js的缺点,为了解决这个问题造js的人它设计一种编程方式(解决问题的方式):异步。而什么时候再去干其它事情,就是事件进行驱动。

常见的应用场景:

(1)网络请求

(2)读取文件

(3)js中的事件函数就是非常典型的异步表现形式。

异步特点:

  • 不阻塞

  • 必须通过回调拿结果

代码演示:使用定时器模拟异步感受异步编程的特点。

  function computedSum( a,b,callback ){
            //假设有网络请求,用时3秒拿到a与b的和

            setTimeout( function(){
                //return a + b
                callback( a + b)
            } ,3000)
           
        }

        // let s1 = computedSum( 10,20 )
        // console.log( s1,'undefined' )

        computedSum( 10,20,function(res){
            console.log( res,'1122233' )
        } )

优化处理异步方式

回调的必要性

   connObj.query(sql1, (err2, result) => {
     req.result = result;
   })
    console.log(req.result);
    //undifined, 这是因为connObj.query()中回调函数为异步。代码先执行同步操作,因此undifined.

回调地狱

​ 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况被称为回调地狱(或回调)。而往往一些异步操作需要使用回调函数拿到结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmrKMXVy-1635505573080)(img/1-2回调函数.png)]

优化回调函数

优化前:层层的嵌套(就是因为有依赖关系)
connObj.query(sql1, (err2, result) => {
	router.post('/adduser', (req, res) => {
   		 form.parse(req, (err1, fields, files) => {

            console.log(req.result);//有结果
                
     })
  })
})
优化后:
async function(){
    const res1 = await 买了彩票
    const res2 = await 中了特等奖500万,等待领奖
    const res3 = await 去还房贷
}

promise

promise简介

  • Promise(许诺) 是异步编程的一种解决方案,就是一个容器,里面保存着某个未来才会结束的事件。

  • Promise 是个构造函数 。许诺的意思 。

语法

基本语法:

new Promise( (resolve,reject)=>{
  //异步任务(){
         resolve() //拿到异步任务里的参数
    	 reject()//错误信息,拿到异步任务里的参数,并报错。
//}      
} )
  • 许诺是不需要花时间的,许诺的那件事(事要去干,是花时间的):这件事是异步的,不会阻塞其它事情

  • new Promise( function(){ })

    1)这个匿名函数会变成同步

    2) Promise的回调中应该放异步代码,同步代码无意义 。

  • Promise 是个构造函数,实例化会返回一个promise对象

let pro1 = new Promise( (resolve,reject)=>{
} )

代码案例2:

    let pro2 = new Promise(function(resolve,reject) {
        //resolve接收then的第一个参数,是一个回调函数。

        //即 resolve = function (values) {
        //     console.log(res, '拿到了一个员工薪水')
        // }

        let slaray = 100000 // 100000
        resolve(slaray) //这个resolve函数实际上执行then里的参数为函数

    })

    // 语法:pro2.then( callback )  //promise对象的原型链上,then :然后的意思 。
    pro2.then(function(values) {
        console.log(values, '拿到了一个员工薪水') //100000 。
    })

promise状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vb43s2Ah-1635505573081)(img\1-4promise状态转换.jpg)]

promise对象方法

then

语法:

promise实例.then( successCallback,errorCallback )
    //successCallback: 是拿成功的结果,也就是resolve函数传递的参数
    //errorCallback: 是拿失败的结果,也就是reject函数传递的参数
let pro1 = new Promise( (resolve,reject)=>{
     //这个函数只能传递1个参数,如需多个则传对象。
    resolve( { a:11,b:22,c:333 } )
    reject( '失败的信息:我没去买彩票' )
} )
    //pending => 成功:OK    : success  : resolve  : fulfilled
    //pending => 失败:error :  error    : reject

pro1.then( (result)=>{ 
    console.log( result,'这是success' )
} ,(err)=>{
    console.log(err,'这是错误信息')
} )

then返回值

  • then方法返回一个promise实例对象,对象状态由回调函数的执行结果决定。

  • 如果回调函数返回一个非promise类型结果,则状态为成功,返回值为这个值。

  • 返回一个promise类型结果,则状态跟随promise状态。

let pro1 = new Promise( (resolve,reject)=>{
    resolve( { a:11,b:22,c:333 } ) //这个函数只能传递1个参数,如需多个则传对象。
    //reject( '失败的信息:我没去买彩票' )
} )
const p = pro1.then( (result)=>{ 
    console.log( result,'这是success' );
    return 123//成功状态,值为123.
    return new Promise(function(resolve,reject){
        resolve(12);//成功状态,值为12.
        reject(1);//失败状态,值为1.
    })
})
log(p);//值

catch

语法:

promise实例对象.catch( (异常)=>{
   //代码块
} )

代码案例:

let pro1 = new Promise( (resolve,reject)=>{
    //resolve( 20 )
    reject(  '数据太大')
} )

pro1.then( (res)=>{
    //console.log(res)
    return res + 30
}  ).then( (res)=>{

        console.log( res ) //50
} ).catch( function(err){
    console.log('无论哪个promise对象调用了reject,都会在这里统一捕获错误' ,err)
} )	

链式调用

代码案例:

let pro1 = new Promise( (resolve,reject)=>{
     fs.readFile('/path1',(err,data)=>{
         resolve(data);
     })	
 } )

pro1.then( (res)=>{
    return new Promise(function(resolve,reject){
       fs.readFile('/path2',(err,data)=>{
         resolve([res,data]);
      })	
    })
})
.then( (res)=>{
        console.log( res ) //[{path1.data},{path2.data}]
} )

async函数

ES2017 标准引入了 async 函数,它是一个关键字,被async修饰的函数称为async函数。

作用:async也是处理异步的,它是对Promise的一种扩展,让异步更加方便,彻底解决回调嵌套

async函数基本用法

注意:

  • async函数返回的也是一个promise对象

  • async函数内部可以写await:等待的意思,其实就是等待你未来要发生事情的结果。后面必须是promise实例对象

  • 如果是同步代码根本就不需要写async函数 。

语法:

// 一般写法
async function name( ){
	let res1 = await promise异步1
	let res2 = await promise异步2
    ...
}

// 箭头函数写法
let fn = async ()=>{
   let res1 =  await promise异步1
   let res2 =  await promise异步2
   ...
}
   
// 在对象里面的写法

{
    async fn(){
          let res1 =  await promise异步1
  		  let res2 =  await promise异步2
   		  ...
    },
   fn1: async function(){
            
   },
   fn3:async ()=>{

   }
}
   
// 点击函数写法
bnt.onclick = async function (){
      let res1 =  await promise异步1
  	  let res2 =  await promise异步2
   	  ...
}

应用

使用async函数把promise的异步变成真正的同步代码

代码案例:

    let pro1 = new Promise((resolve) => {
        setTimeout(() => {
            let a = 1
            let b = 2
            resolve(a + b)
        }, 3000)
    })

    //await 只能存在于async函数内。否则报错
    async function fn2() {
        let result1 = await pro1 //await后跟promise实例对象 
        //会帮我们自动调用then函数并返回then的参数并实现同步。
        console.log(result);
    }

    fn2()

模块化封装数据库

(1)新建db.js

(2)自定义模块注意使用module.exports暴露方法

const mysql = require('mysql')
const connOBj = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'root',
    database:'web803',
    port:3306
})

function myQuery(sql){
    return new Promise ( (resolve)=>{
        connOBj.query( sql,( err,result )=>{
            resolve( {result,err} )
        } )
    } )

}

module.exports = myQuery

//下面是个使用myQuery的一个小demo,需要写类似这样的async函数 。
 async function fn1(){
    let values = await  myQuery( `SELECT * FROM student WHERE id=3` )
     console.log( values,'我在async函数内拿到的结果' )
}
fn1()

暴露方法

const mysql = require('mysql')
const connOBj = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'root',
    database:'web803',
    port:3306
})

function myQuery(sql){
    return new Promise ( (resolve)=>{
        connOBj.query( sql,( err,result )=>{
            resolve( {result,err} )
        } )
    } )

}

module.exports = myQuery

//下面是个使用myQuery的一个小demo,需要写类似这样的async函数 。
 async function fn1(){
    let values = await  myQuery( `SELECT * FROM student WHERE id=3` )
     console.log( values,'我在async函数内拿到的结果' )
}
fn1()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值