| |
|
开发:
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图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 8:48:59- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |