| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> 大数据 -> Node.js中 promise与异步 -> 正文阅读 |
|
|
[大数据]Node.js中 promise与异步 |
一、Node操作Mysql1.1 介绍和意义1.2 操作流程1.2.1 下载mysql模块npm i mysql 1.2.2 在后端js文件中引入mysqlconst 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)=>{ })
nodejs通过msyql包操作mysql数据库的步骤【重点】: 第一步:引入mysql包 第二步:创建mysql连接:mysql.createConnection(); 第三步:开始连接mysql: mysqlObj.connect(); 第四步:执行sql语句:mysqlObj.query('sql语句'[,参数值],回调方法); nodejs通过msyql包操作mysql数据库的代码实例1: //第一步:引入mysql包
const mysql = require('mysql');
// console.log(mysql);
?
//第二步:创建mysql连接:mysql.createConnection();
const mysqlObj = mysql.createConnection({ host: 'localhost', port: 3306, user: 'root', password: 'root', database: 'mydemo' });
// console.log(mysqlObj);
?
//第三步:开始连接mysql: mysqlObj.connect();
mysqlObj.connect();
?
//第四步:执行sql语句:mysqlObj.query('sql语句'[,参数值],回调方法);
// let sql = `insert into class(banji,teacher)values('go语言开发','张老师')`;
// let sql = `select * from xsb where szx='计算机系'`;
// let sql = `select * from xsb where szx=?`;
let sql = `insert into class(banji,teacher)values(?,?)`;
?
// let val = '数学系';
// let val = '信息系';
?
let val = 'web开发3班';
let teachers = '张老师';
mysqlObj.query(sql, [val, teachers], (err, data) => {
? ?console.log(err, data);
? ?// for (let obj of data) {
? ?// ? ? console.log(`姓名:${obj.xm} 年龄:${obj.age} 所在系:${obj.szx}`);
? ?// }
});
nodejs通过msyql包操作mysql数据库的代码实例2: const express = require('express');
const path = require('path');
const mysql = require('mysql');
?
const app = express();
?
app.listen(3000, () => {
? ?console.log('3000端口');
});
?
//第二步:创建mysql连接:mysql.createConnection();
const mysqlObj = mysql.createConnection({ host: 'localhost', port: 3306, user: 'root', password: 'root', database: 'mydemo' });
// console.log(mysqlObj);
?
//第三步:开始连接mysql: mysqlObj.connect();
mysqlObj.connect();
?
app.use(express.urlencoded({ extended: false }));
//设置ejs:
app.set('view engine', 'ejs'); //设置模板引擎为ejs
app.set('views', [`${path.join(__dirname,'moban')}`]); //设置模板文件的存放位置
app.engine('html', require('ejs').__express); //将html文件作为ejs模板文件来解析
?
?
//显示搜索界面:
app.get('/', (req, res) => {
?
?
? ?res.render('find.html');
});
?
//处理查询学生:
app.post('/', (req, res) => {
?
? ?//接参(用户输入的要查询姓名)
? ?let { usr = '' } = req.body;
? ?if (usr == '') {
? ? ? ?res.send(`<script>alert('学生姓名不能为空');location.href='/';</script>`);
? ? ? ?return;
? }
?
? ?let sql = `select * from xsb where xm like '%${usr}%'`;
? ?let str = '';
? ?mysqlObj.query(sql, (err, data) => {
?
? ? ? ?for (let obj of data) {
? ? ? ? ? ?str += `<div>姓名:${obj.xm} 年龄:${obj.age}</div>`;
? ? ? }
?
?
? ? ? ?res.send(str);
? });
});
find.html文件代码如下: <!DOCTYPE html> <html lang="en"> ? <head> ? ?<meta charset="UTF-8"> ? ?<meta http-equiv="X-UA-Compatible" content="IE=edge"> ? ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ?<title>Document</title> </head> ? <body> ? ?<form action="/" method="post"> ? ? ? ?<input type="text" name="usr" placeholder="请输入要查询的学生姓名"> ? ? ? ?<button>搜索</button> ? ?</form> </body> ? </html> 二、promise与异步2.1什么是Promise【重点】Promise是异步编程的解决方案之一(异步编程中数据传递或回调嵌套的问题),Promise实际上是一个许诺器,它里面通常放的是将来要执行的异步代码,这些代码执行完成后会有两种结果:成功或失败,因此Promise有三种状态:pending(初始状态)、success/fullfill(成功状态)、reject(失败状态),当我们在Promise内部调用了成功时的回调方法resolve()时则把Promise的pending(初始状态)转换成success/fullfill(成功状态),当我们在Promise内部调用了失败时的回调方法reject()时则把Promise的pending(初始状态)转换成reject(失败状态)。 Promise的特点:【重点】 1、Promise内部的代码是以同步方式执行的; 2、通过Promise对象调用多个then()方法,但调用多个catch()没有意义; 3、在then()方法中可以通过return返回具体的值或Promise对象给后面的then()传递参数值; 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 promise2.5.1 promise简介Promise(许诺) 是异步编程的一种解决方案,就是一个容器,里面保存着某个未来才会结束的事件。 2.5.2 语法:基本语法: new Promise( (resolve,reject)=>{
// resolve()
// reject()
} )
代码案例: <script>
//Promise内部的代码是以同步方式执行的
console.log('111');
new Promise(() => {
console.log(222);
});
console.log(333);
</script>
2.5.3 promise状态2.5.4 promise对象方法2.5.4.1 then注意:Promise对象的then()调用完成后返回的是Promise对象 语法: promise对象.then( (结果)=>{
//代码块
} )
<script>
let prm = new Promise((resolve, reject) => {
// if (1) {
if (0) {
resolve('OK'); //调用成功时的回调函数
} else {
reject('出错了'); //调用失败时的回调函数
}
});
prm.then(function(d) {
console.log(d, 222);
}, function(e) {
console.log(e, 888);
});
//Promise对象的then()调用完成后返回的是Promise对象
console.log(prm.then(), 666);
</script>
2.5.4.2 catch注意:Promise对象的catch()调用完成后返回的是Promise对象 语法: promise对象.catch( (异常)=>{
//代码块
} )
代码案例: <script>
let prm = new Promise((resolve, reject) => {
// if (1) {
if (0) {
resolve('OK'); //调用成功时的回调函数
} else {
reject('出错了'); //调用失败时的回调函数
}
});
prm.then(function(d) {
console.log(d, 222);
}).catch(function(e) {
console.log(e, 777);
});
</script>
2.5.5 链式调用【重点】注意:1)、可以通过Promise对象调用多个then()方法,但只需要调用一次catch()方法 2)、在then()方法中可以通过return返回具体的值或Promise对象给后面的then()传递参数值; 代码案例: <script>
let prm2 = new Promise((resolve, reject) => {
setTimeout(() => {
// if (1) {
if (0) {
resolve('Helllo');
} else {
reject('这是错误信息');
}
}, 2000);
});
// prm2.then((d) => {
// console.log(d, 11);
// }).then((d2) => {
// console.log(d2, 222);
// }).then(d3 => {
// console.log(d3, 333);
// }).catch(e => {
// console.log(e, 999);
// });
prm2.then(d => {
console.log(d, 111);
}).catch(e => {
console.log(e, 333);
}).catch(e2 => {
console.log(e2, 555);
}).catch(e3 => {
console.log(e3, 666);
});
function demo(data) {
return new Promise((resolve, reject) => {
if (1) {
resolve(data);
} else {
reject('失败了');
}
});
}
let p = demo('A');
p.then(d => {
console.log(d, 111);
return demo('B');
// p = demo('B');
// p.then(d2 => {
// console.log(d2, 222);
// }).catch(e2 => {
// console.log(e2);
// });
}).then(d2 => {
console.log(d2, 222);
// return demo('C');
return 'Yes OK';
}).then(d3 => {
console.log(d3, 333);
}).catch(e => {
console.log(e, 9999);
});
</script>
2.5.6 Promise.all():并发方法该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,也就是说通过all()方法来同时执行多个不同的Promise实例。 Promise.all()方法的特点: 1)、all()方法中的所有Promise实例都执行成功时返回的是一个数组,数组的元素值与all()方法中的Promise实例一一对应; 2)、all()方法中只要有一个Promise实例执行失败则all()方法就执行失败,如果all()方法中的Promise实例都执行失败则返回的值是最先失败的Promise实例的结果; 3)、all()要么都成功,要么都失败; 语法: Promise.all( [ Promise实例1,Promise实例2,... ] ) 代码案例: <script>
function test1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (1) {
//if (0) {
resolve('Hello WEB');
} else {
reject('失败了');
}
}, 3000);
});
}
function test2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (1) {
// if (0) {
resolve('Yes OK');
} else {
reject('出错。。。');
}
}, 2000);
});
}
// let prm = Promise.all([test1(), test2()]);
let prm = Promise.all([test2(), test1()]);
// console.log(prm);
prm.then(data => {
console.log(data, 111);
}).catch(err => {
console.log(err, 999);
});
</script>
三、async函数ES2017 标准引入了 async 函数,它是一个关键字,被async修饰的函数称为async函数。 作用:async函数是异步编程解决方案之一,它是以同步流程表达异步操作。它是对Promise的一种扩展,让异步更加方便,彻底解决回调嵌套 async函数的特点:【重点】 1)、async的特点: (1)、async可以单独使用; (2)、async函数调用完成后返回的是Promise对象; <script>
function demo() {
}
// console.log(demo()); // undefined
async function fn() {
}
console.log(fn()); //async函数调用后返回的是Promise对象
// fn().then(d => {
// console.log(d, 999);
// }).catch(e => {
// console.log(e);
// })
</script>
2)、await的特点:【重点】 (1)、await不能单独使用,必须与async一起使用; (2)、await通常等待的Promise的结果,对于Promise的成功时回调函数的结果可以直接处理, 对于Promise的失败时回调函数的结果不能直接处理,但有两种解决方法: 第一种解决办法:通过Promise对象的catch()方法来定义失败时的回调函数,代码如下: <script>
function mydemo() {
return new Promise((resolve, reject) => {
setTimeout(() => {
//需求:返回'Hello Web!!'
console.log('Hello Web!!');
if (1) {
// if (0) {
resolve([true, 'Hello Web33333!!']);
} else {
reject('失败了');
}
}, 3000);
});
}
async function myfn() {
console.log('开始');
//第一种解决办法:通过Promise对象的catch()方法来定义失败时的回调函数
let data = await mydemo().catch(err => {
console.log(err, 7777);
});
console.log(data, '执行完成!!');
}
myfn();
</script>
第二种解决办法:在Promise内部不管理执行成功或失败都调用成功时的回调方法resolve()方法,然后在resolve()方法中传递数组,数组的格式为:[true/false,值],代码如下: <script>
function mydemo() {
return new Promise((resolve, reject) => {
setTimeout(() => {
//需求:返回'Hello Web!!'
console.log('Hello Web!!');
if (1) {
// if (0) {
// resolve();
resolve([true, 'Hello Web33333!!']);
} else {
//第二种解决办法:在Promise内部不管理执行成功或失败都调用成功时的回调方法resolve()方法,然后在resolve()方法中传递数组,数组的格式为:[true/false,值]
// reject('失败了');
resolve([false, '失败了']);
}
}, 3000);
});
}
async function myfn() {
console.log('开始');
//第一种解决办法:通过Promise对象的catch()方法来定义失败时的回调函数
// let data = await mydemo().catch(err => {
// console.log(err, 7777);
// });
let [flg, data] = await mydemo();
if (flg) {
console.log(data, '执行完成!!');
} else {
console.log(data, '执行失败...');
}
}
myfn();
</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()); // undefined
async function fn() {
}
console.log(fn()); //async函数调用后返回的是Promise对象
// fn().then(d => {
// console.log(d, 999);
// }).catch(e => {
// console.log(e);
// })
</script>
3.2 应用使用async函数把promise的异步变成真正的同步代码 代码案例: <script>
function mydemo() {
return new Promise((resolve, reject) => {
setTimeout(() => {
//需求:返回'Hello Web!!'
console.log('Hello Web!!');
if (1) {
// if (0) {
// resolve();
resolve([true, 'Hello Web33333!!']);
} else {
//第二种解决办法:在Promise内部不管理执行成功或失败都调用成功时的回调方法resolve()方法,然后在resolve()方法中传递数组,数组的格式为:[true/false,值]
// reject('失败了');
resolve([false, '失败了']);
}
}, 3000);
});
}
async function myfn() {
console.log('开始');
//第一种解决办法:通过Promise对象的catch()方法来定义失败时的回调函数
// let data = await mydemo().catch(err => {
// console.log(err, 7777);
// });
let [flg, data] = await mydemo();
if (flg) {
console.log(data, '执行完成!!');
} else {
console.log(data, '执行失败...');
}
}
myfn();
</script>
四、模块化封装数据库(1)新建db.js文件并使用module.exports暴露方法,代码如下:【重点】 const mysql = require('mysql');
const mysqlObj = mysql.createConnection({ host: 'localhost', user: 'root', password: 'root', port: 3306, database: 'mydemo' });
mysqlObj.connect();
function exec(sql) {
return new Promise((resolve, reject) => {
mysqlObj.query(sql, (err, data) => {
// console.log(err, data, 8888);
//需求:返回data
if (err) { //失败
resolve([false, err]);
} else { //成功
resolve([true, data]);
}
});
});
}
// exec('select * from xsb ');
// exec(`insert into class(banji,teacher)values('php开发','王老师')`).then(d => {
// let [flg, arr] = d;
// }).catch(e => {});
// async function test() {
// let sql = 'select * from xsb';
// let [err, datas] = await exec(sql);
// if (err) {
// console.log(datas);
// for (let obj of datas) {
// console.log(`姓名:${obj.xm} 所在系:${obj.szx}`);
// }
// } else {
// console.log(`sql出错了:${datas}`);
// }
// }
// test();
module.exports = exec;
(2),使用上面定义的db.js模块文件来操作msyql数据库,代码如下: let mysqlExec = require('./6-dbMysql.js');
// console.log(mysqlExec);
const express = require('express');
const app = express();
app.listen(4000, () => {
console.log('4000端口');
});
app.get('/', async(req, res) => {
let { xm = '' } = req.query;
let sql = `select * from xsb where xm like '%${xm}%'`;
// mysqlExec(sql).then().catch();
let [err, arr] = await mysqlExec(sql);
console.log(err, arr);
res.send(`查询结果为:${JSON.stringify(arr)}`);
});
app.get('/dmeo', async(req, res) => {
let sql = 'select * from cjb';
let [err, arr] = await mysqlExec(sql);
});
|
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/26 22:42:05- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |