一、Node操作Mysql
1.1 介绍和意义
1.2 操作流程
1.2.1 下载mysql模块
npm i mysql
1.2.2 在后端js文件中引入mysql
const mysql = require('mysql')
1.2.3 先创建mysql数据库的配置连接
let connectObj = mysql.createConnection({
host:'主机名',
user:'用户名',
password:'密码'
port:'端口号',
database:'要操作哪个数据库'
})
1.2.4 使用connectObj.query
使用query方法执行sql语句
connectObj.query(sqlStr,(err,results)=>{ })
实例代码:
const express = require('express');
const path = require('path');
const app = express();
app.listen(3000, () => {
console.log('3000端口');
});
//第一步:在项目根目录下安装msyql包: npm i mysql
//第二步:引入mysql包
const mysql = require('mysql');
// console.log(mysql);
//第三步:创建mysql连接:mysql.createConnection()
let mysqlObj = mysql.createConnection({ host: '127.0.0.1', port: 3306, user: 'root', password: 'root', database: 'mydemo' });
// console.log(mysqlObj, 666);
//第四步:开始连接mysql
mysqlObj.connect();
//根据用户输入的姓名查询学生信息:
app.get('/search', (req, res) => {
//获取用户输入的姓名:
let { uname = '', banji = '', teacher = '' } = req.query;
if (uname == '') {
res.send(`<script>alert('请输入要查询的学生姓名')</script>`);
return;
}
//根据用户输入的姓名查询学生信息:
// let sql = `select * from xsb where xm like '%${uname}%'`;
// let sql = `select * from xsb where xm like ?`;
let sql = `insert into banji(banji,teacher)values(?,?)`;
// mysqlObj.query(sql, (err, data) => {
// mysqlObj.query(sql, `%${uname}%`, (err, data) => {
mysqlObj.query(sql, [`${banji}`, `${teacher}`], (err, data) => {
res.send(data);
});
});
二、promise与异步
2.1简介
Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理。
2.2 同步
代码演示:(1)使用alert介绍同步阻塞(2)使用函数计算两个数的和调用后用变量接收
什么是同步?【重点】
就是在当前调用发出之后在没有得到结果之前后续代码不会执行,一直处在在线等待状态。同步是阻塞的
2.3 异步
常见的应用场景:(1)网络请求(2)读取文件(3)js中的事件函数就是非常典型的异步表现形式。
代码演示:使用定时器模拟异步感受异步编程的特点。
什么是异步?【重点】
在当前调用发出之后 在没有得到结果之前后续代码可以执行,当前调用结果会以通知、回调函数的方式告诉调用者。异步是非阻塞的
2.4 回调函数
2.4.1 简介
在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况被称为回调地狱(或回调)。而往往一些异步操作需要使用回调函数拿到结果
2.4.2 表现形式
2.4.3 优化回调函数
优化前:
fn1( function(买彩票){
fn2( function(中奖){
fn3( function(还房贷){
} )
} )
} )
优化后:
async function(){
const res1 = await 买了彩票
const res2 = await 中了特等奖500万,等待领奖
const res3 = await 去还房贷
}
2.5 promise
2.5.1 promise简介
Promise(许诺) 是异步编程的一种解决方案,就是一个容器,里面保存着某个未来才会结束的事件。
什么是Promise?【重点】
Promise是一个许诺器,它是异步编程解决方案之一,Promise里面通常放的是将来要执行的异步代码,这些代码执行完成后会有两种结果:成功或失败,因此Promise有三种状态:pending(初始状态)、fullfilled/resolve(成功状态)、rejected(失败状态),当在Promise内部调用了成功时的回调函数resolve()时则把Promise的pending初始状态转换成fullfilled/resove成功状态,同时执行定义在then()方法的第一个参数位置定义的成功时的回调函数;当在Promise内部调用了失败时的回调函数reject()时则把Promise的pending初始状态转换成reject失败状态,同时执行定义在then()方法的第二个参数位置或catch()方法中定义的失败时的回调函数;
Promise的特点:【重点】
1)、Promise内部的代码是以同步方式来执行的;
<script>
console.log(111);
//定义Promise:
let prm = new Promise(function() {
console.log(222);
});
console.log(333);
</script>
2.5.2 语法:
基本语法:
new Promise( (resolve,reject)=>{
// resolve()
// reject()
} )
代码案例:
<script>
// console.log(111);
// //定义Promise:
// let prm = new Promise(function() {
// console.log(222);
// });
// console.log(333);
console.log(111);
//resolve:成功时要执行的回调函数
//reject:失败时要执行的回调函数
let prm = new Promise(function(resolve, reject) {
// console.log(resolve, 666);
// console.log(reject, 8888);
setTimeout(() => {
// console.log(222);
//需求:返回222
if (1) {
//if (0) {
resolve(222); //执行(调用)成功时的回调函数
} else {
reject('出错信息...'); //执行(调用)失败时的回调函数
}
}, 2000);
});
//console.log(prm, 9999);
prm.then(function(data) {
console.log(`成功 ${data}`);
}, function(e) {
console.log(`失败: ${e}`);
});
console.log(333);
</script>
2.5.3 promise状态
2.5.4 promise对象方法
2.5.4.1 then
语法:
promise对象.then( (结果)=>{
//代码块
} )
2.5.4.2 catch
语法:
promise对象.catch( (异常)=>{
//代码块
} )
代码案例:
<script>
// console.log(111);
// //定义Promise:
// let prm = new Promise(function() {
// console.log(222);
// });
// console.log(333);
console.log(111);
//resolve:成功时要执行的回调函数
//reject:失败时要执行的回调函数
let prm = new Promise(function(resolve, reject) {
// console.log(resolve, 666);
// console.log(reject, 8888);
setTimeout(() => {
// console.log(222);
//需求:返回222
if (1) {
//if (0) {
resolve(222); //执行(调用)成功时的回调函数
} else {
reject('出错信息...'); //执行(调用)失败时的回调函数
}
}, 2000);
});
//注意:Promise对象的then()执行完成后返回的是Promise对象
// console.log(prm.then(), 9999);
prm.then(function(data) {
console.log(`${data} 成功`);
}).catch(function(e) {
console.log(`${e} 失败`);
});
console.log(333);
</script>
2.5.5 链式调用()
1)、可以定义多个then()方法,但定义多个catch()没有意义,只需要定义一个catch()方法即可
代码案例:
<script>
let prm = new Promise((resolve, reject) => {
if (0) {
resolve();
} else {
reject();
}
});
// prm.then(() => {
// console.log(`成功1`);
// }).then(() => {
// console.log('成功2');
// }).then(() => {
// console.log('成功3');
// }).catch(() => {
// console.log('失败了');
// });
//console.log(prm.catch());
prm.then(() => {
console.log('成功');
}).catch(() => {
console.log('失败1');
}).catch(() => {
console.log(`失败2`);
}).catch(() => {
console.log('失败3');
});
function test(p) {
return new Promise((resolve, reject) => {
if (1) {
resolve(p);
} else {
reject('失败了');
}
});
}
let prm = test('A');
// console.log(prm);
prm.then(data => {
console.log(`成功:${data}`);
return test('B'); //返回Promise对象
// return 'Yes OK'// 返回具体的值
// let prm2 = test('B');
// prm2.then(d => {
// let prm3 = test('C')
// }).catch(() => {
// });
}).then(data2 => {
console.log(`成功2: ${data2}`);
return test('C');
}).then(data3 => {
console.log(`成功3: ${data3}`);
}).catch(err => {
console.log(err);
});
</script>
2.5.6 Promise.all()
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
什么是前端并发?
就是在同一个时间点内执行多个不同的操作,比如:想同时获取到首页的轮播图数据和同步课程数据。
Promise的并发方法all()的特点:
1)、all()执行成功时返回的结果为数组,数组中的元素值与all()方法中的Promise实例一一对应;
2)、all()方法中的Promise实例有一个失败时则返回最先失败的Promise实例的结果;
3)、all()方法中的promise实例要么都执行成功,要么都执行失败;
语法:
Promise.all( [ Promise实例1,Promise实例2,... ] )
代码案例:
<script>
function demo1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// if (1) {
if (0) {
resolve('Hello web');
} else {
reject('错误信息');
}
}, 3000);
});
}
function demo2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (1) {
// if (0) {
resolve('Yes OK');
} else {
reject('出错了。。。');
}
}, 2000);
});
}
// let prm = Promise.all([demo1(), demo2()]);
let prm = Promise.all([demo2(), demo1()]);
// console.log(prm);
prm.then(d => {
console.log(d, 777);
}).catch(e => {
console.log(e, 888);
});
</script>
三、async函数
ES2017 标准引入了 async 函数,它是一个关键字,被async修饰的函数称为async函数。
async函数的作用【重点】:async也是处理异步的,它是异步编程解决方案之一,async函数是以同步流程表达异步操作,它是对Promise的一种扩展,让异步更加方便,彻底解决回调嵌套
async的特点:【重点】
1)、async可以单独使用;
2)、async函数调用完成后返回的是Promise对象;
<script>
function demo() {
}
//console.log(demo(), 666); // undefined
//定义async函数:
async function test() {
}
console.log(test(), 1111); //返回Promise对象
</script>
await的特点 :【重点】
1)、await不能单独使用,要与async一起使用;
2)、await可以直接处理Promise函数成功时回调函数的结果,不能直接处理Promise函数的失败时回调函数的结果,有两种解决办法:
第一种:在Promise对象后面调用catch()方法,在catch()方法中定义失败时的回调函数,代码如下:
<script>
function mytest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('Hello WEB!!');
//需求:返回'Hello WEB!!'
if (0) {
// if (1) {
resolve('Hello WEB!!');
} else {
reject('这是错误信息');
}
}, 3000);
});
}
async function my() {
console.log('开始执行');
let data = await mytest().catch(err => {
console.log(`出错了:${err}`);
});
console.log(`${data} 完成...`);
}
my();
</script>
第二种:在Promise内部不管执行成功还是失败都调用成功时的回调函数resolve()方法,在resolve()方法中返回数组,数组的格式类似于这样:[true/false,结果],代码如下:
<script>
function mytest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('Hello WEB!!');
//需求:返回'Hello WEB!!'
// if (0) {
if (1) {
resolve([true, 'Hello WEB!!']);
} else {
// reject('这是错误信息');
resolve([false, '这是错误信息']);
}
}, 3000);
});
}
async function my() {
console.log('开始执行');
//第一种解决办法:
// let data = await mytest().catch(err => {
// console.log(`出错了:${err}`);
// });
//第二种解决办法:
let [flg, data] = await mytest();
if (flg) {
console.log(`${data} 成功...`);
} else {
console.log(`${data} 失败...`);
}
}
my();
</script>
3.1 async函数基本用法
注意:async函数返回的也是一个promise对象
async语法:【重点】
// 一般写法
async function name( ){
let res1 = await promise异步1
let res2 = await promise异步2
...
}
// 箭头函数写法
async ()=>{
let res1 = await promise异步1
let res2 = await promise异步2
...
}
// 在对象里面的写法
{
async fn(){
let res1 = await promise异步1
let res2 = await promise异步2
...
}
}
// 点击函数写法
bnt.onclick = async ()=>{
let res1 = await promise异步1
let res2 = await promise异步2
...
}
代码案例:
<script>
function demo() {
}
//console.log(demo(), 666); // undefined
//定义async函数:
async function test() {
}
// console.log(test(), 1111); //返回Promise对象
// let prm = test();
// prm.then(d => {
// console.log('成功');
// }).catch(e => {
// console.log('失败');
// });
// function fn() {
// await 123; //await is only valid in async functions and the top level bodies of modules
// }
// fn(); //await不能单独使用,要与async一起使用
async function myfn() {
console.log(`开始`);
let data = await 'Hello';
console.log(`${data} 执行到这里`);
data = await 99;
console.log(`${data} 完成...`);
}
// myfn();
function mytest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('Hello WEB!!');
//需求:返回'Hello WEB!!'
// if (0) {
if (1) {
resolve([true, 'Hello WEB!!']);
} else {
// reject('这是错误信息');
resolve([false, '这是错误信息']);
}
}, 3000);
});
}
async function my() {
console.log('开始执行');
//第一种解决办法:
// let data = await mytest().catch(err => {
// console.log(`出错了:${err}`);
// });
//第二种解决办法:
let [flg, data] = await mytest();
if (flg) {
console.log(`${data} 成功...`);
} else {
console.log(`${data} 失败...`);
}
}
my();
</script>
3.2 应用
使用async函数把promise的异步变成真正的同步代码
代码案例:
<script>
function mytest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('Hello WEB!!');
//需求:返回'Hello WEB!!'
// if (0) {
if (1) {
resolve([true, 'Hello WEB!!']);
} else {
// reject('这是错误信息');
resolve([false, '这是错误信息']);
}
}, 3000);
});
}
async function my() {
console.log('开始执行');
//第一种解决办法:
// let data = await mytest().catch(err => {
// console.log(`出错了:${err}`);
// });
//第二种解决办法:
let [flg, data] = await mytest();
if (flg) {
console.log(`${data} 成功...`);
} else {
console.log(`${data} 失败...`);
}
}
my();
</script>
四、模块化封装数据库
(1)新建db.js
(2)使用module.exports暴露方法
封装mysql.js模块文件,代码如下:
//需求:封装一个功能模块来操作mysql数据库//第二步:引入mysql包
//引入mysql包
const mysql = require('mysql');
//创建mysql数据库连接:
const mysqlObj = mysql.createConnection({ host: "127.0.0.1", port: 3306, user: "root", password: "root", database: "mydemo" });
//连接mysql数据库:
mysqlObj.connect();
//执行sql语句:
function exec(sql) {
return new Promise((resolve, reject) => {
//执行sql语句:
mysqlObj.query(sql, (err, data) => {
//需求:返回data
if (err) { //失败
resolve([false, 'sql语句错误']);
} else { //成功
resolve([true, data]);
}
});
});
}
module.exports = exec;
使用上面封装好的mysql.js模块文件,代码如下:
let mysqlExec = require('./myql.js');
// console.log(mysqlExec, 999);
async function test() {
let sql = 'select * from kcb';
let [error, data] = await mysqlExec(sql);
if (error) {
for (let obj of data) {
console.log(`课程名:${obj.kcm}`);
}
} else {
console.log('sql执行失败');
}
}
test();