最近在用Node.js编写一个后端逻辑,里面涉及到Mysql的联表查询(即用一个表的查询结果去查另一个表),这时就需要多层回调函数嵌套。那么问题就来了,多层回调函数嵌套就会产生“回调地狱”的问题,代码结构非常难看,而Promise和async就是为了解决“回调地狱”而产生的解决方案。我选择了Promise,但是在代码结构方面遇到了一些问题,最后经过大佬的指点解决了,特此记录。
首先要安装mysql模块(在已安装Mysql的前提下):
npm install -s mysql
然后执行(这里是我犯的错误,正确代码在后面):
/*
注意这是一段错误的代码
*/
const mysql = require('mysql');
// 建立连接
let connection = mysql.createConnection({
host: '127.0.0.1', // 数据库地址
port: '3306', // 数据库端口
user: 'root', // 用户名
password: '', // 密码
database: '' // 数据库名称
});
// Promise异步执行
let prom = Promise.resolve();
prom.then(function () {
// 执行查询
connection.query('SELECT * FROM users_table;', (e, result) => { // 这里users_table是我的表名,请读者自行替换
console.log('Search complete!');
if (e) {
throw e;
}
connection.end(); // 关闭连接,否则程序不会自动退出
return Promise.resolve(result);
});
})
.then(function (data) {
console.log('Search result: ', data);
});
输出结果如下:
Search result: undefined
Search complete!
可以看到,then()方法先执行了,然后mysql才返回结果,说明mysql的异步执行并没有被Promise监视,Promise以为程序已经执行完毕,因此进入下一步了。
经过继续学习Promise,得到正确的Promise异步执行代码如下:
const mysql = require('mysql');
// 建立连接
let connection = mysql.createConnection({
host: '127.0.0.1', // 数据库地址
port: '3306', // 数据库端口
user: 'root', // 用户名
password: '', // 密码
database: '' // 数据库名称
});
// Promise异步执行
let prom = Promise.resolve();
prom.then(function () {
// 执行查询
return new Promise(resolve => {
connection.query('SELECT * FROM users_table;', (e, result) => { // 这里users_table是我的表名,请读者自行替换
console.log('Search complete!');
if (e) {
throw e;
}
connection.end(); // 关闭连接,否则程序不会自动退出
resolve(result);
});
});
})
.then(function (data) {
console.log('Search result: ', data);
});
结果:
Search complete!
Search result: [
// some data
]
执行成功。
经过总结反思,我对Promise.then()的理解是,then()方法返回一个Promise对象,而then()本身不是异步方法,并没有进行异步回调的监听,所以真正的异步函数应该放在返回的Promise对象中,而Promise对象会对resolve()方法进行监听,实现异步执行。