IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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操作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)=>{  })

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="请输入要查询的学生姓名">&nbsp;
 ? ? ? ?<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 promise

2.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);
});

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:41:10  更:2021-11-30 15:42:58 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码