【发布时间】:2022-02-14 16:03:13
【问题描述】:
我是node.js和mysql的新手,之前问过类似的问题,但是我的整个服务器很混乱,所以我花了一些时间改进它。但我回到了异步问题: 如何处理同步和异步 MYSQL 查询执行:我的注册功能将首先运行查询以查看用户是否已注册,如果没有,则在数据库中创建用户。
// create a new user
User.signUp = (user, result) => {
flag = true
// Does Email adress has been registered?
sql.query(`SELECT * FROM user_info WHERE EMAIL_ADRESS = ?`, user.username, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
if (res.length) {
//=========tell that it is registered=======/
console.log("found user: ", res[0]);
let judge = {
isRegistered: true,
};
result(null, judge);
flag = false
return;
}
});
// If not found: insert the user
if(flag){
console.log('No!!!!!!! in')
const uLoginAuth = {
USER_ID: user.id,
EMAIL_ADRESS: user.username,
PSWORD:user.password,
VERIFIED: false,
VERIFYCODE: uuid.v1()
};
const uInfo = {
USER_ID: user.id,
FIRST_NME: user.firstName,
LAST_NME: user.lastName,
USER_ROLE: user.role,
EMAIL_ADRESS: user.username
};
sql.query("INSERT INTO user_info SET ?", uInfo, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created user: ", { id: res.insertId, ...user });
});
sql.query('INSERT INTO login_authentication SET ?', uLoginAuth, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created user: ", { id: res.insertId, ...user });
});
let judge = {
isRegistered: true,
};
result(null, judge);
return;
}
};
但是,我收到一个错误:error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client,这意味着我发回了两次响应,所以我设置了 console.log 来查看,然后我意识到,当用户已经注册时,我确实得到了正确的回复:
{
"isRegistered": true
}
但是代码在注释后执行处理正常注册的行 // 如果没有找到 这是程序的输出:
Server is running on port 8080.
Successfully connected to the database.
No!!!!!!! in
found user: RowDataPacket {
USER_ID: 'b7f632ef-a8b9-489f-b3eb-c8f25c2b5a32',
FIRST_NME: 'Test',
LAST_NME: 'Test',
USER_ROLE: 'student',
EMAIL_ADRESS: 'test@gmail.com'
}
我尝试了多种方式等待第一个查询完成后再执行下一行,但它不起作用,在这种情况下,有人可以帮我解决这个问题吗?我怎么能等到查询完成?谢谢!!!!!!!!!
【问题讨论】:
-
对于 Web 服务器,您应该始终假设更新是异步的,因为多个浏览器客户端可以同时触发多个更新。那是在考虑攻击者使用脚本触发大量查询之前。一种常见的模式是尝试插入,然后如果失败则尝试更新。对于您的情况,可能会尝试创建,然后如果失败,请转到“帐户已存在”处理程序。