目 录CONTENT

文章目录

NodeJS异步编程解决方案

Administrator
2020-07-24 / 0 评论 / 0 点赞 / 12013 阅读 / 7091 字

NodeJS异步编程解决方案

在JS里面,异步编程是JS的基础,我们会看到很多代码都是异步执行的,例如jQuery里面的动画 ,Ajax里面的请,MySQL与WebSQL的数据库操作,像这些都是异步。

在之前的异步编程里面,我们使用的解决方案都是回调,例如jQuery里面的动画回调, Ajax里面的回调,MySQL操作的回调,setTimtout也是一个异步的。

在最开始的异步解决方案里面,我们使用的是回调来解决异步的返回值的问题,今天我们把前端常见的三种异步解决方案总结一下

回调方法解决异步编程

回调的使用场景非常多,它既可以解决控制权的问题,也可以解决异步的问题,现在我们使用setTimeout的方式来模拟一个异步操作

function abc(callBack) {
    //我们使用setTimeout 5秒钟以后,生成一个0~100之间的随机数,
    //如果这个随机数大于60,则返回及格 ,否则返回不及格
    setTimeout(() => {
        let temp = parseInt(Math.random() * 100);
        let result = temp >= 60 ? "及格" : "不及格";
        if (typeof callBack == "function") {
            callBack(result);
        }
    }, 5000);
}


abc(result => {
    console.log(`你的成绩是: ${result}`);
});

我们将之前封装的DBUtil.js 的代码使用回调完成一次

DBUtils.js代码

const mysql = require("mysql");

/**
 * @class DBUtil
 * @description  数据库操作核心对象
 */
class DBUtil {
    /**
     * @name getConn 获取数据库连接
     * @description 静态方法,获取数据库的连接
     * @returns {object} conn数据库连接
     */
    static getConn() {
        let conn = mysql.createConnection({
            host: "127.0.0.1",
            port: 3306,
            user: "root",
            password: "aaabbb",
            database: "test",
            multipleStatements: true
        });
        conn.connect();
        return conn;
    }
    /**
     * 
     * @param {string} strSql 要执行的SQL语句 
     * @param {function} callBack    执行SQL语句以后的回调操作
     * @param {Array} params      执行SQL语句所需要的参数
     */
    static executeSql(strSql, callBack, params = []) {
        let conn = DBUtil.getConn();
        conn.query(strSql, params, (err, result) => {
            if(typeof callBack=="function"){
                callBack(err,result);
            }
            conn.end();
        });
    }
}
module.exports=DBUtil;

调用上面的方法进行测试

const DBUtil=require("./utils/DBUtil.js");
function abc(){
    let strSql="select * from stuinfo";
    DBUtil.executeSql(strSql,(err,result)=>{
        if(err){
            //说明数据库执行失败了
            console.log(err);
        }
        else{
            //说明数据库执行成功了
            console.log(result);
        }
    });
}
abc();

NodeJS里面使用事件对象解决

在NodeJS里面自带的模块包里面有一个模块包叫events,这个包是事件包

方法的本质可以理解为“用户触发事件,事件调用方法”。当用户去触发这个事件的时候,事件就会调用一个方法,所以我们可以根据一个像这样的思路去完成异步操作

/**
 * 异步编程第二种解决方案 events事件
 */

//我们使用setTimeout 5秒钟以后,生成一个0~100之间的随机数,
//如果这个随机数大于60,则返回及格 ,否则返回不及格

//使用NodeJS自带的模块包
const events = require("events");
function abc() {
    //创建一个事件出来
    let event = new events.EventEmitter();
    setTimeout(() => {
        let temp = parseInt(Math.random() * 100);
        if(temp<60){
            event.emit("catch","不及格");
        }
        else{
            event.emit("then","及格");
        }
    }, 1000);
    return event;   //返回刚刚创建的事件对象
}

abc().on("then",result=>{
    console.log(result);
}).on("catch",err=>{
    console.log(err);
});

现在我们通过这个方法来封装数据库的异步操作

DBUtils.js代码

const mysql = require("mysql");
const events = require("events");

/**
 * @class DBUtil
 * @description  数据库操作核心对象
 */
class DBUtil {
    /**
     * @name getConn 获取数据库连接
     * @description 静态方法,获取数据库的连接
     * @returns {object} conn数据库连接
     */
    static getConn() {
        let conn = mysql.createConnection({
            host: "127.0.0.1",
            port: 3306,
            user: "root",
            password: "aaabbb",
            database: "test",
            multipleStatements: true
        });
        conn.connect();
        return conn;
    }
    /**
     * 
     * @param {string} strSql 要执行的SQL语句 
     * @param {function} callBack    执行SQL语句以后的回调操作
     * @param {Array} params      执行SQL语句所需要的参数
     */
    static executeSql(strSql, params = []) {
        let event=new events.EventEmitter();
        let conn = DBUtil.getConn();
        conn.query(strSql, params, (err, result) => {
            if(err){
                event.emit("catch",err);
            }
            else{
                event.emit("then",result);
            }
            conn.end();
        });
        return event;
    }
}
module.exports = DBUtil;

测试上面的方法

const DBUtil=require("./utils/DBUtil2.js");
function abc(){
    let strSql="select * from stuinfo";
    DBUtil.executeSql(strSql).on("then",result=>{
        //代表数据库执行成功
        console.log(result);
    }).on("catch",err=>{
        //代表数据库执行失败
        console.log(err);
    });
}
abc()

注意events是NodeJS的自带模块,只能在NodeJS里面使用,如果想在浏览器的环境下面去使用我们需要下载第三方框架,例如onfire.js框架


使用ES6里面的Promise解决

Promise是ES6里面新出的对象,用用于处理异步编程的,它是一个构造函数,本内自带三个状态(具体可以看之前的笔记)

/**
 * 使用promise来解决异步编程
 */


function abc() {
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            let temp = parseInt(Math.random() * 100);
            if (temp < 60) {
                //拒绝
                reject("你的分数不够,不能参加科目二考试 ,请回去好好学习");
            } else {
                //继续
                resolve(temp);
            }
        }, 1000);
    });
    return promise;
}
abc().then(result=>{
    //代表resolve的结果
    console.log(`你的得分得:${result},可以继续下一轮考试`);
}).catch(err=>{
    //代表reject的结果
    console.log(`拒绝操作,原因是:${err}`);
})

上面的代码使用了promise的方式来进行,在ES6里面,promise可以转换为同步代码

上面的代码转换为同步以后,如下所示

/**
 * 使用promise来解决异步编程
 */


function abc() {
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            let temp = parseInt(Math.random() * 100);
            if (temp < 60) {
                //拒绝
                reject("你的分数不够,不能参加科目二考试 ,请回去好好学习");
            } else {
                //继续
                resolve(temp);
            }
        }, 1000);
    });
    return promise;
}

async function def() {
    try {
        let result = await abc();
        console.log(`你的得分得:${result},可以继续下一轮考试`);
    }
    catch (err) {
        console.log(`拒绝操作,原因是:${err}`);
    }
}
def();
  • await不能暴露在全局使用,并且在async的方法里面使用
  • await等待到的只能是resolve()的结果,如果是reject()会自动跳到catch的异常里面去
0

评论区