繁体   English   中英

意图返回之前循环返回的NodeJS MySQL查询

[英]NodeJS MySQL query in loop returning before intented

我正在尝试创建一个函数,该函数将生成4个唯一的ID(十六进制)以插入到我的数据库中。 我将查询放入do while循环中以检查冲突,如果代码已经存在,则重新生成代码,如果不存在,则返回值。

问题是循环在预期的时候退出。 例如,如果生成了代码“ a”但已经在数据库中显示了该代码,则将重新生成该代码,但是循环将退出,并且永远不会进行新的查询。 新代码不会返回-而是返回生成的第一个代码。

这是我的代码:

const FIND_EXISITNG_COURT =
  "SELECT access_code,team1,team2 FROM courts WHERE access_code= ?";

function generateAccessCode() {

  var random = Math.floor(Math.random() * (+30 - +0)) + +0;
  var code = random.toString(16);

  var hasDupe = false;

  do {
      connection.query(FIND_EXISITNG_COURT, [code], (err, results) => {

          if (err) {
              throw err;
          } else if (results.length > 0) {
              random = Math.floor(Math.random() * (+30 - +0)) + +0;
              code = random.toString(16);

              hasDupe = true;
          } else {
              hasDupe = false;
          }
      });
  } while (hasDupe);

  return code;
}

我是NodeJS的新手,所以我不知道这样做是否不好。 任何帮助将非常感激!

在您的代码中, query回调函数将在数据准备好后再运行,因此hasDupe首次为false并将返回生成的代码。

您可以使用Promiseasync功能来解决您的问题

const FIND_EXISITNG_COURT =
"SELECT access_code,team1,team2 FROM courts WHERE access_code= ?";

function selectByCode(code) {  
    return new Promise((resolve, reject) => {
        connection.query(FIND_EXISITNG_COURT, [code], (err, results) => {
        if (err) {
            reject(err);
        } else {
            resolve(results.length)
        }
    });
}

async function generateAccessCode() {

    var random = Math.floor(Math.random() * (+30 - +0)) + +0;
    var code = random.toString(16);

    var hasDupe = false;

    let count =0;
    try{
        do {

            count = await selectByCode(code);
            if (count > 0) {
                random = Math.floor(Math.random() * (+30 - +0)) + +0;
                code = random.toString(16);

                hasDupe = true;
            } else {
                hasDupe = false;
            }


        } while (hasDupe);

        return code;
    }
    catch(e){
        throw e;

    }
}

您对connection.query调用是异步的,这意味着您定义的回调不会立即运行。 您的代码只注册该回调,然后继续执行直到generateAccessCode结束。 直到很久以后(当数据库返回某些信息时),回调才被调用,因此hasDupe仅在退出原始函数后很长时间hasDupe设置。

基本上,您有3个选项可以处理此问题:回调,promise或async / await(实际上只是在promises之上的语法糖)。

使用async / await的示例,但尝试尽可能地保持与原始结构的距离(多次运行以查看其工作原理):

 // this is a mock for the db call. This "database" already holds records with IDs 0, 2 and 3. // IRL you will need to wrap your db call in a function that returns a promise // if you want to do it this way const connectionQuery = function (code) { return new Promise((resolve) => { setTimeout(() => resolve(code === 1 ? [] : [true]), 1000); }); } async function generateAccessCode() { // simplified the code generation for this example let code = Math.floor(Math.random() * 4); // Code can be 0, 1, 2, or 3 let hasDupe = false; let results; do { results = await connectionQuery(code); // await here is the key if (results.length > 0) { console.log(`Code ${code} already exists in the database. Generating new code...`); code = Math.floor(Math.random() * 4); hasDupe = true; } else { hasDupe = false; } } while (hasDupe); return code; } generateAccessCode() .then((code) => { console.log(`Final result: ${code}`); }) .catch((err) => { console.log(err); }); 

改用回调:

 // this is a mock for the db call. This "database" already holds records with IDs 0, 2 and 3. const connectionQuery = function (code, callback) { setTimeout(() => { callback(null, code === 1 ? [] : [true]); }, 1000); } function generateAccessCode(callback) { // simplified the code generation for this example let code = Math.floor(Math.random() * 4); // Code can be 0, 1, 2, or 3 let hasDupe = false; let results; connectionQuery(code, (err, results) => { if (err) { return callback(err); } if (results.length) { console.log(`Code ${code} already exists in the DB`); return generateAccessCode(callback); } callback(null, code); }); } generateAccessCode((err, code) => { console.log(`Final result: ${code}`); }); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM