【问题标题】:how to handle assynchronous SQL query execution in node.js如何在 node.js 中处理异步 SQL 查询执行
【发布时间】: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 服务器,您应该始终假设更新是异步的,因为多个浏览器客户端可以同时触发多个更新。那是在考虑攻击者使用脚本触发大量查询之前。一种常见的模式是尝试插入,然后如果失败则尝试更新。对于您的情况,可能会尝试创建,然后如果失败,请转到“帐户已存在”处理程序。

标签: mysql node.js async.js


【解决方案1】:

所以,如果我没记错的话,这就是您要在这里尝试的内容:

  1. 在用户注册时,您正在尝试检查用户是否已存在于 DB 中。
  2. 如果没有,则将其插入数据库。
  3. 在任何一种情况下,您都会将其作为响应返回:
{
    isRegistered: true
}

您所做的if 检查并未等待第一个查找/选择操作完成,因此在调用signUp 函数时会立即触发(很可能是在用户访问signUp 路由时)。

这就是您可以在“找到的用户:...”日志(异步,在 DB 操作之后显示)之前看到“No!!!!!!! in”控制台(同步,立即显示)的原因。

要解决此问题,您可以像这样构建代码:

User.signUp = (user, result) => {
  let judge = { 
    isRegistered: 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]);
      } else { // <-------------- can make it "else if (preferred condition)" too
        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 });      
        });
      }

      result(null, judge);
  });
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 2010-11-21
    • 1970-01-01
    • 2022-06-12
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    相关资源
    最近更新 更多