【问题标题】:My NodeJS MySQL Query function always returns wrong results我的 NodeJS MySQL 查询函数总是返回错误的结果
【发布时间】:2019-08-22 21:28:52
【问题描述】:

我正在开发一款使用 MySQL 进行多人游戏的游戏。现在,每次我请求查询(例如

dat("SELECT * FROM server1;"); 

它不会给我server1的数据,而是返回

的结果
dat("SELECT * FROM highscore;");

即使我尝试其他命令,例如

dat("SELECT * FROM playernames;");

)。所以我的函数似乎自动保存了我在开始时所做的初始化的查询,并在每次使用该函数时执行它。

我尝试过在网上搜索新功能,我尝试过 Promise,但我是新手,我无法处理 PROMISES 我不知道如何处理它们,所以我使用 async 和等待

async function dat(Befehl) {
  console.error(Befehl);
  con.connect(function(err) {
    if (err) throw err;
    console.log("MySQL: Connected to localhost!");
    con.query("USE abschlussprojekt;", function (err, result) {
      if (err) throw err;
      console.log(result);
    });
  });
  con.query(Befehl, function (err, result) {
    if (err) throw err;
    //await Sleep(10);
    while(result == undefined)
    {}
    temp = result;
    delete result;
  });
  return temp;
  con.close();
}

所以

let x = await dat("SELECT * FROM server1;"); 

我希望:

Player1Cards = "Cards"
Player1CardsColour = "Colour";
Player2Cards = "Cards";
Player2CardsColour = "Colour";
Player1Name = "Name"
Player2Name = "Name"

但它会返回高分表,我不知道,为什么。

但是!!!当我重复调用同一个函数时,我可能会得到真正的结果。就像在我调用它 3-6 次之后一样。

这里也是使用查询的函数。

async function generateTable()
{
  let highscoredata = [];
  //await Sleep(3000);
   highscoredata = await loadhighscore();
   while(highscoredata === undefined)
   {
     highscoredata = await loadhighscore();
     await Sleep(10);
   }
   //else {

    console.log(highscoredata);

    if (gen>0) {
      await Sleep(500);
      gen--;
      generateTable();
    }
    else {
      var Spielername = [];
      var Spiel = [];
      var Highscore = [];
      await Sleep(100);
      for (var i = 0; i < highscoredata.length; i++) {
        Spielername[i] = highscoredata[i].Name;
        Spiel[i] = highscoredata[i].Spiel;
        Highscore[i] = highscoredata[i].Highscore;
        if (CONLOG) {
          console.log("SpielerName: "+Spielername);
        }
      }

      console.log("Daten implementiert");
      let table = document.getElementById("table");
      document.getElementById("table").innerHTML = "";
      var row, SpielerID1 = [], SpielerName1 = [], SpielArt1 = [], Highscore1 = [];
      for( var i = Spielername.length-1; i>-1; i--)
      {
        //console.log(Spielername);
        //console.log(i);
        row = await table.insertRow(0); //TR Element Neue Spalte

        SpielerID1[i] = await row.insertCell(0); //SpielerID
        SpielerName1[i] = await row.insertCell(1); //SpielerName
        SpielArt1[i] = await row.insertCell(2); //Spiel
        Highscore1[i] = await row.insertCell(3); //Score

        SpielerID1[i].innerHTML = i;
        SpielerName1[i].innerHTML = Spielername[i];
        SpielArt1[i].innerHTML = Spiel[i];
        Highscore1[i].innerHTML = Highscore[i];

      }
      //console.log(SpielerName);
      row = await table.insertRow(0);
      var stdID = await row.insertCell(0); //SpielerID
      var stdSN = await row.insertCell(1); //SpielerName
      var stdSP = await row.insertCell(2); //Spiel
      var stdSC = await row.insertCell(3); //Score

      stdID.innerHTML = "ID";
      stdSN.innerHTML = "Spieler";
      stdSP.innerHTML = "Spiel";
      stdSC.innerHTML = "Score";
    }

出于调试原因清除所有服务器的功能

function AlleFreigeben()
{
  dat("UPDATE INUSE SET Server1 = FALSE;");
  dat("UPDATE INUSE SET Server2 = FALSE;");
  dat("UPDATE INUSE SET Server3 = FALSE;");
  dat("UPDATE INUSE SET Server4 = FALSE;");
  dat("UPDATE INUSE SET Server5 = FALSE;");
  console.warn("Alle Server wurden wieder freigegeben!");
}

这里还有一个登录功能。

async function prelogin()
{

  preuser = await dat("SELECT * FROM users;"); //Everytime, this function is executed, it gets the results from the wrong table, so just ONE execution
  login(preuser);
}

async function login(user)
{
  preuser = await dat("SELECT * FROM users WHERE username = '"+document.getElementById("usernameinput").value+"';");
  console.warn(preuser);
if (preuser[0].password == await md5(document.getElementById("passwordinput").value)) {
  console.warn("Passwort korrekt");
  alert("Login erfolgreich");
  isUserLoggedIn = true;
  document.getElementById("Spieler1NameFeldHM").value = preuser[0].username;
  reverse(true);
  CPUTable();
}
else {
  alert("Falsches Passwort");
  console.error("Passwort falsch");
}
}

当然还有注册函数

async function register()
{
  if (document.getElementById("usernameinput").value == "") {
    alert("Geben Sie einen Benutzernamen ein");
  }
  else if (document.getElementById("usernameinput").value.length <3) {
    alert("Der Nutzername darf nicht weniger als 3 Zeichen haben")
  }
  else if (document.getElementById("usernameinput").value == "root") {
    alert("Ey, ich bin schon Admin");
  }
  else {
    let dbuser = await dat("SELECT * FROM users WHERE username = '"+document.getElementById("usernameinput").value+"';");
    console.log(dbuser);
    if (dbuser.length != 0) {
      if (document.getElementById("usernameinput").value == dbuser[0].username) {
        console.error(document.getElementById("usernameinput").value);
        console.error(await dat("SELECT * FROM users WHERE username = '"+document.getElementById("usernameinput").value+"';"));
        alert("Benutzername ist bereits vergeben");
      }
    }

    else {
      await dat("INSERT INTO users VALUES('"+document.getElementById("usernameinput").value+"', '"+md5(document.getElementById("passwordinput").value)+"');");
      alert("Registrierung erfolgreich!");
      prelogin();
    }
  }
}

这里还有一个将名字推送到表格中并开始游戏的功能。

async function UnoStartHM()
{
  await dat("UPDATE spielernamen SET Spieler1 = '"+document.getElementById("Spieler1NameFeldHM").value+"';");
  await dat("UPDATE spielernamen SET Spieler2 = '"+document.getElementById("Spieler2NameFeldHM").value+"';");
  location.href = "./Uno.html";
}

但是,除了手动执行 mysql 查询(通过控制台)之外,这是唯一不起作用的功能

async function Abfrage()
{
  if (confirm("Möchtest du im lokalen Multiplayer spielen?")) { //If local multiplayer is confimed
    Multiplayer = true;
    myEmitter.setMaxListeners(100);
    console.log(myEmitter);
    let SpielerNamen = await dat("SELECT * FROM spielernamen");
    //Spieler1Name = SpielerNamen[0]
    Server1 = await dat("SELECT * FROM INUSE;");
    // Server1 = await dat2("SELECT * FROM INUSE;");
    // Server1 = await dat2("SELECT * FROM INUSE;");
    //Erzeuge Tabelle, falls sie noch nicht existiert!
    await dat("CREATE TABLE IF NOT EXISTS INUSE (Server1 boolean NOT NULL, Server2 boolean NOT NULL, Server3 boolean NOT NULL, Server4 boolean NOT NULL, Server5 boolean NOT NULL);");
    await Sleep(100);
    // await dat("INSERT INTO INUSE VALUES (FALSE, FALSE, FALSE, FALSE, FALSE);");
    await dat_alt();
    //await dat(" UPDATE INUSE SET Server2 = FALSE WHERE INUSE.Server2 IS NULL; UPDATE INUSE SET Server3 = FALSE WHERE INUSE.Server3 IS NULL; UPDATE INUSE SET Server4 = FALSE WHERE INUSE.Server4 IS NULL; UPDATE INUSE SET Server5 = FALSE WHERE INUSE.Server5 IS NULL;");
    //await dat("UPDATE INUSE SET Server2 = FALSE WHERE INUSE.Server2 IS NULL;");
    //await dat2("UPDATE INUSE SET Server3 = FALSE WHERE INUSE.Server3 IS NULL;");
    //await dat("UPDATE INUSE SET Server4 = FALSE WHERE INUSE.Server4 IS NULL;");
    //await dat2("UPDATE INUSE SET Server5 = FALSE WHERE INUSE.Server5 IS NULL;");
    console.warn("TABLE INITIALISIERT");
    Server1 = await dat("SELECT * FROM INUSE;");
    console.log("Verbinde mit Datenbank...");
    await Sleep(1000);
    console.log("Verbunden");
    console.log(typeof Server1);
    console.log(Server1);
    let errcount = 0;
    while (Server1 === undefined && errcount < 6) {
      errcount++;
      await Sleep(100);
      if (errcount == 5) {
        alert("Datenbank konnte nicht geladen werden. Bitte versichere, dass die Datenbank existiert");
        if (confirm("Möchtest du zum Hauptmenü zurückkehren?")) {
          location.href = "./index.html";
        }
        else {
          break;
        }
      }
      console.log(errcount);
      console.log("Erneut");
      // Server1 = await dat("SELECT * FROM INUSE;");
      // console.log(Server1);
      // await Sleep(10);
    }
    console.log(Server1);
    console.log(myEmitter);
    if (Server1[0].Server1 == 0) {
      await dat("UPDATE INUSE SET Server1 = TRUE;"); //Server 1 belegen || Use Server 1
       belegt = 1;
       belegt2 = belegt;
       //return belegt;
    }
    else if (Server1[0].Server2 == 0) {
      await dat("UPDATE INUSE SET Server2 = TRUE;"); //Server 2 belegen
      const belegt = 2;
      belegt2 = belegt;
      //return belegt;
    }
    else if (Server1[0].Server3 == 0) {
      await dat("UPDATE INUSE SET Server3 = TRUE;"); //Server 3 belegen
      const belegt = 3;
      belegt2 = belegt;
      //return belegt;
    }
    else if (Server1[0].Server4 == 0) {
      await dat("UPDATE INUSE SET Server4 = TRUE;"); //Server 4 belegen
      const belegt = 4;
      belegt2 = belegt;
      //return belegt;
    }
    else if (Server1[0].Server5 == 0) {
      await dat("UPDATE INUSE SET Server5 = TRUE;"); //Server 5 belegen
      const belegt = 5;
      belegt2 = belegt;
      //return belegt;
    }
    else {
      alert("Zurzeit sind alle Server belegt... bitte versuche es später noch einmal!"); //Alle Server belegt
      location.reload();
    }
    alert("Es wurde Server "+belegt2+" ausgewählt!");

    await dat("UPDATE SERVER"+belegt2+" SET Spieler1IP = '"+IPAdresse+"'; UPDATE SERVER"+belegt2+" SET Spieler1Name = '"+Spieler1Name+"';");
    WaitForPlayer();
    return belegt;
  }
}

【问题讨论】:

  • 您是否在某处的另一个函数中使用高分表调用查询?如果您重新运行应用程序 6 次并在第 6 次获得预期结果,听起来您在某处有某种类型的 raise 条件,并且您正在看到获胜的函数的输出。如果不看到您的更多代码,我认为我们将无法提供太多帮助。您能否发布更多代码以向我们展示该程序的全部范围?
  • 我已经用所有使用查询的功能更新了我的帖子

标签: javascript mysql node.js npm mysql2


【解决方案1】:

问题是变量 temp 由您之前请求的查询设置,甚至在数据库回答查询之前返回。我强烈建议研究 Promises。

以下代码正在执行问题中的代码应该执行的操作。记下方法 resolve()reject() 的调用位置。

async function connect() {
  return new Promise((resolve, reject) => {
    // Assuming con is defined somewhere above.
    con.connect(function(err) {
      if (err) return reject(err);
      console.log("MySQL: Connected to localhost!");
      con.query("USE abschlussprojekt;", function (err, result) {
        if (err) return reject(err);
        console.log(result);
        return resolve();
      });
    });
  })
}

async function query(Befehl) {
  return new Promise((resolve, reject) => {
    con.query(Befehl, function (err, result) {
      if (err) return reject(err);

      return resolve(result);
    });
  })
}

async function dat(Befehl) {
  await connect();
  const result = await query(Befehl);
  con.close();
  return result;
}

Promise 帮助:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

异步帮助:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

【讨论】:

  • 感谢您的帮助,但显然我的代码现在...似乎卡住了,不再做任何事情。甚至文件系统似乎也不起作用。就像我的项目只是冻结而没有抛出错误。现在非常令人困惑的是它还活着。
  • 很抱歉听到这个消息。这意味着 Async 函数之一或 Promise 之一永远不会返回。不解决或拒绝。
猜你喜欢
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 2022-12-02
  • 2014-02-20
  • 1970-01-01
  • 2021-02-03
  • 2017-12-12
  • 2012-10-06
相关资源
最近更新 更多