nodejs wait/async与嵌套的mysql查询

jchrr9hc  于 2021-06-17  发布在  Mysql
关注(0)|答案(3)|浏览(491)

我需要有关此代码的帮助:

var sqlCheckIfExist = "SELECT my_refer FROM hub_user WHERE my_refer = '" + friendReferCode + "'";
var sqlCodeCheckSameAsMine = "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'";

async function checkIfUserCodeExist() {
  connection.promise().query(sqlCheckIfExist)
    .then(([rows, fields]) => {
    if (rows == 0) {
      console.log("Non esiste!")
      return res.send(JSON.stringify({
        "status": 500,
        "response": "codeNotExist"
      }));
    }
    checkIfCodeIsSameAsMine()
    console.log("Esiste!")
    console.log(rows[0].my_refer);
  })
    .catch(console.log)
    .then(() => connection.end());
}

async function checkIfCodeIsSameAsMine() {
  connection.promise().query(sqlCodeCheckSameAsMine)
    .then(([rows, fields]) => {
    if (rows == friendReferCode) {
      console.log("Codice uguale!")
      return res.send(JSON.stringify({
        "status": 500,
        "response": "sameCodeAsMine"
      }));
    }
    console.log("Codice non uguale!")
  })
    .catch(console.log)
    .then(() => connection.end());
}

checkIfUserCodeExist()

我是这样建立联系的:

app.use(function(req, res, next) {
  global.connection = mysql.createConnection({
    host: 'xx',
    user: 'xx',
    password: 'xx',
    database: 'xx'
  });
  connection.connect();
  next();
});

我不明白一件事:如何调用嵌套查询?在checkifusercodeexist()函数中检查rows==0时,如果为false,则调用checkifcodeissameasmine(),但出现以下错误:

Error: Can't add new command when connection is in closed state
at Connection._addCommandClosedState (/usr/myserver/node_modules/mysql2/lib/connection.js:135:17)
at Connection.end (/usr/myserver/node_modules/mysql2/lib/connection.js:836:26)
at connection.promise.query.then.catch.then (/usr/myserver/addReferFriend.js:45:31)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)

我怎么能修好那东西?
我把完整的文件贴在这里:

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.post('/', function(req, res, next) {
    var uid = req.body.uid;
    var friendReferCode = req.body.friendReferCode;

    var sqlCheckIfExist = "SELECT my_refer FROM hub_user WHERE my_refer = '" + friendReferCode + "'";
var sqlCodeCheckSameAsMine = "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'";
async function checkIfUserCodeExist() {
    connection.promise().query(sqlCheckIfExist)
    .then( ([rows,fields]) => {
            if (rows == 0) {
                console.log("Non esiste!")
                return res.send(JSON.stringify({"status": 500,"response": "codeNotExist"}));
            }
            checkIfCodeIsSameAsMine()
            console.log("Esiste!")
            console.log(rows[0].my_refer);
    })
    .catch(console.log)
    .then( () => connection.end());
    }

    async function checkIfCodeIsSameAsMine() {
        connection.promise().query(sqlCodeCheckSameAsMine)
        .then( ([rows,fields]) => {
                if (rows == friendReferCode) {
                    console.log("Codice uguale!")
                    return res.send(JSON.stringify({"status": 500,"response": "sameCodeAsMine"}));
                }
                console.log("Codice non uguale!")
        })
        .catch(console.log)
        .then( () => connection.end());
        }

checkIfUserCodeExist()
});

module.exports = router;

提前谢谢!

2j4z5cfb

2j4z5cfb1#

这可能是因为您在checkifusercodeexist函数的末尾终止了连接。删除以下行,我认为它会起作用:

connection.end()

或者,每次创建方法时都要打开和关闭的连接将返回新连接并在进行任何db查询之前调用它。例子:

function getMysqlConnection() {
     const connection = mysql.createConnection({
         host: 'xx',
         user: 'xx',
         password: 'xx',
         database: 'xx'
     });
     connection.connect();
     return connection;
 }

 var sqlCheckIfExist = "SELECT my_refer FROM hub_user WHERE my_refer = '" + friendReferCode + "'";
 var sqlCodeCheckSameAsMine = "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'";
 async function checkIfUserCodeExist() {
     const connection = getMysqlConnection();
     connection.promise().query(sqlCheckIfExist)
         .then(([rows, fields]) => {
             if (rows == 0) {
                 console.log("Non esiste!")
                 return res.send(JSON.stringify({ "status": 500, "response": "codeNotExist" }));
             }
             checkIfCodeIsSameAsMine()
             console.log("Esiste!")
             console.log(rows[0].my_refer);
         })
         .catch(console.log)
         .then(() => connection.end());
 }

 async function checkIfCodeIsSameAsMine() {
     const connection = getMysqlConnection();
     connection.promise().query(sqlCodeCheckSameAsMine)
         .then(([rows, fields]) => {
             if (rows == friendReferCode) {
                 console.log("Codice uguale!")
                 return res.send(JSON.stringify({ "status": 500, "response": "sameCodeAsMine" }));
             }
             console.log("Codice non uguale!")
         })
         .catch(console.log)
         .then(() => connection.end());
 }

 checkIfUserCodeExist()
yfwxisqw

yfwxisqw2#

您的程序中有多个问题需要更新。
首先,不能使用全局变量来存储每个请求的数据库连接。如果两个请求同时到达,那么一个请求将覆盖 connection 因此,您可能会对两个请求使用相同的连接,和/或不关闭其中一个连接,从而导致挂起连接,在最坏的情况下,这可能会导致应用程序无响应。
要解决此问题,必须传递与请求对象的连接:

app.use(async function(req, res, next) {
  try {
    if( req.dbConnection ) {
      // ensure that req.dbConnection was not set already by another middleware
      throw new Error('req.dbConnection was already set')
    }

    let connection = mysql.createConnection({
      host: 'xx',
      user: 'xx',
      password: 'xx',
      database: 'xx'
    });

    res.on("finish", function() {
      // end the connection after the resonponse was send
      req.dbConnection.end()
    });

    // assign a promise base version of connection to request
    req.dbConnection = connection.promise()

    // wait for the connection to be established
    await connection.connect();
    next();
  } catch(err) {
    next(err);
  }
});

要访问按请求定义的连接,您可以执行以下操作:

app.get('/', async function(req, res, next) {
   try {
     await checkIfUserCodeExist(req.dbConnection)

     // so something here after `checkIfUserCodeExist` finished
   }  catch(err) {
     next(err); // if an error occured pass it to the next
   }
})
``` `async` 是用来搭配的吗 `await` 如果你没有 `await` 在你的身体里你就不需要 `async` 在函数之前。
如果你没有 `await` 在函数体中,您需要从函数返回承诺链,以便调用者可以等待函数完成:

function checkIfUserCodeExist(connection) {
return connection.query(sqlCheckIfExist)
.then(([rows, fields]) => {
if (rows == 0) {
console.log("Non esiste!")

    return res.send(JSON.stringify({
      "status": 500,
      "response": "codeNotExist"
    }));
  }
  console.log("Esiste!")
  console.log(rows[0].my_refer);
  return  checkIfCodeIsSameAsMine(connection)
})

}

function checkIfCodeIsSameAsMine(connection) {
return connection.query(sqlCodeCheckSameAsMine)
.then(([rows, fields]) => {
if (rows == friendReferCode) {
console.log("Codice uguale!")
return res.send(JSON.stringify({
"status": 500,
"response": "sameCodeAsMine"
}));
}
console.log("Codice non uguale!")
})
}

如果你想和我一起去 `async` 它看起来是这样的:

async function checkIfUserCodeExist(connection) {
let [rows, fields] = await connection.query(sqlCheckIfExist)

if (rows == 0) {
console.log("Non esiste!")
return res.send(JSON.stringify({
"status": 500,
"response": "codeNotExist"
}));
}

await checkIfCodeIsSameAsMine()

console.log("Esiste!")
console.log(rows[0].my_refer);
}

async function checkIfCodeIsSameAsMine(connection) {
let [rows, fields] = await connection.query(sqlCodeCheckSameAsMine)

if (rows == friendReferCode) {
console.log("Codice uguale!")
return res.send(JSON.stringify({
"status": 500,
"response": "sameCodeAsMine"
}));
}

console.log("Codice non uguale!")
}

你应该避免这样的事情:

return res.send(JSON.stringify({
"status": 500,
"response": "codeNotExist"
}));

相反,您将抛出一个自定义错误,如:

throw new CustomError(500, "codeNotExist")

并有一个错误:

app.use(function(err, req, res, next) {
return res.send({
"status": err.status,
"response": err.message
});
})

因此,只有一个地方可以创建错误响应,并且可以在必要时对错误响应进行更改,例如添加一些额外的日志记录。
编辑(以匹配更新的问题)

/* GET users listing. */
router.post('/', function(req, res, next) {
var uid = req.body.uid;
var friendReferCode = req.body.friendReferCode;

var sqlCheckIfExist = "SELECT my_refer FROM hub_user WHERE my_refer = '" + friendReferCode + "'";
var sqlCodeCheckSameAsMine = "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'";

function checkIfUserCodeExist() {
return req.dbConnection.query(sqlCheckIfExist)
.then(([rows, fields]) => {
if (rows == 0) {
console.log("Non esiste!")

      return res.send(JSON.stringify({
        "status": 500,
        "response": "codeNotExist"
      }));
    }
    console.log("Esiste!")
    console.log(rows[0].my_refer);
    return checkIfCodeIsSameAsMine(connection)
  })

}

function checkIfCodeIsSameAsMine() {
return req.dbConnection.query(sqlCodeCheckSameAsMine)
.then(([rows, fields]) => {
if (rows == friendReferCode) {
console.log("Codice uguale!")
return res.send(JSON.stringify({
"status": 500,
"response": "sameCodeAsMine"
}));
}
console.log("Codice non uguale!")
})
}

checkIfUserCodeExist()
.catch(next)
});

0s0u357o

0s0u357o3#

好吧,你的代码有多个问题。我将从解决您的具体问题开始,然后给出一些额外的提示。:)
你的问题就在于这个逻辑:

connection.promise().query(sqlCheckIfExist)
    .then(([rows, fields]) => {
    // some code 

    checkIfCodeIsSameAsMine()

   // some code
  })
    .catch(console.log)
    .then(() => connection.end());

这个 checkIfCodeIsSameAsMine() 函数是异步的。所以,在这个代码链中发生的是 checkIfCodeIsSameAsMine() 但你不要等待它的结果,并立即跳到最后 then() 关闭数据库连接。因此,本质上,在 checkIfCodeIsSameAsMine() 正在关闭连接后执行。
你应该 return checkIfCodeIsSameAsMine() . 这样你就可以等待 Promise 该功能的响应。
现在我要补充一点。
第一, "SELECT my_refer FROM hub_user WHERE uid = '" + uid + "'"; 很糟糕。将应用程序暴露于sql注入等漏洞。您应该通过一些解析功能来转义sql查询中的动态值。这通常是通过orm(即 connection() 你用的)。
第二,如果你使用 async 然后函数使用相应的 await 功能。这样地:

async function checkIfUserCodeExist() {
  let rows, fields;

  try {
    [rows, fields] = await connection.promise().query(sqlCheckIfExist);
  } catch (err) {
    console.log(err);
  }
  if (rows == 0) {
    console.log("Non esiste!");
    return res.send(JSON.stringify({
      "status": 500,
      "response": "codeNotExist"
    }));
  }
  console.log("Esiste!");
  console.log(rows[0].my_refer);

  let result;
  try {
    result = await checkIfCodeIsSameAsMine();
  } catch (err) {
    console.log(err);
  }

  // do something with "result" if you wish

  await connection.end();
}

相关问题