NodeJS asynchronous request about MySQL
Description
NodeJS连接mysql数据库的请求是异步操作。现有客户想要注册,NodeJS需要连接数据库,查询用户表,若用户表中无此用户名方予以注册,否则拒绝。很明显,我需要获取查询的结果之后来决定是否将注册信息写入数据库,“查询”与“写入”这两个异步操作有明显的先后顺序,需要“回调”,用ES6的Promise能更好地解决这一问题。
当我没意识到异步操作时
const connection = require("./connect.js")
module.exports = function (username, password, callback) {
connection.query('use blogs', function (err, res) {
if(err) throw err;
console.log("Database changed : " + res);
})
let flag = false;
connection.query('select * from users', function (err, res) {
if(err) throw err;
let len = res.length;
for(let i = 0; i < len; ++i) {
if(res[i].username === username) {
callback('The username was registered!');
flag = true;
break;
}
}
})
console.log(flag);
if(flag === false) {
const sql = 'insert into users(username, password) values("' + username + '", "' + password + '")'
connection.query(sql, function (err, res) {
if(err) throw err;
console.log("Succeed : " + res);
})
}
}
上述代码
console.log(flag)
最先执行,然后“写入”操作很有可能先于“查询”操作
Promise
const connection = require("./connect.js")
module.exports = function (username, password) {
new Promise((resolve, reject) => {
connection.query('use blogs', function (err) {
if(err) reject(err);
else resolve('Database changed!')
})
}).then(function (info) {
console.log(info);// Database changed!
return new Promise((resolve, reject) => {
connection.query('select * from users', function (err, res) {
if(err) reject(err);
else {
let flag = false
let len = res.length;
for(let i = 0; i < len; ++i) {
if(res[i].username === username) {
reject('The username was registered!');
flag = true;
break;
}
}
if(flag === false) resolve();
}
})
})
}, function (err) {
console.log('Maybe the database did not change : ' + err);
}).then(function () {
return new Promise((resolve, reject) => {
const sql = 'insert into users(username, password) values("' + username + '", "' + password + '")'
connection.query(sql, function (err) {
if(err) reject(err);
else resolve('Insert!');
})
})
}, function (err) {
console.log('Maybe the username exists: ' + err);
}).then(function (info) {
if(info) console.log(info);
}, function (err) {
console.log('Maybe insert error occurred: ' + err);
})
}
catch与then混用不太好,一个Promise对应then,但却不是简单地对应一个catch,可以多个then对应一个catch,这个catch只捕捉第一次出现的错误。所以只用then比较好。
另外如果某个Promise未被执行,它的then中的reslove()函数也会被执行,所以这里最后我判断了一下
if(info)
,如果info不是undefined认为其Promise被调用了,认为是执行成功了。