使用 mysql2 async/await 时出现“发送给客户端后无法设置 headers” 错误
`Cannot set headers after they are sent to client` error when using mysql2 async/await
我正在更改我的后端(从 Mongo 切换到 MySql)。我知道会抛出错误,因为 return 语句在我的 SQL 查询完成之前执行,然后当我的 sql 查询完成时,它会发送另一个 res.send
,因此我尝试将 mysql2
与 Promise 包装器一起使用,以便在我的 async
函数中的查询中使用 await
。
我有一个创建数据库连接的单独文件,因此我可以在整个 Nodejs 后端访问该连接:
const mysql = require('mysql2');
async function pool(){
const pool = await mysql.createPool({
host: "ip",
user: "username",
password: "password",
database: "db"
});
return pool
}
exports.getConnection = async function(callback) {
const currentPool = await pool();
currentPool.getConnection(function(err, conn) {
if(err) return callback(err);
callback(err,conn)
});
};
然后,创建一个遵循 async/await:
的查询
sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
我也试过在查询中使用 await
:
await sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
我错过了什么?我还没有厌倦使用普通的 mysql
NPM 库并制作我自己的 promise 包装器...
新代码:
我更新了我的功能:
const mysql = require('mysql2');
const pool = mysql.createPool({
host: "ip",
user: "user",
password: "pass",
database: "db"
});
exports.db = (sql) => {
new Promise((resolve, reject) => {
pool.getConnection((err, conn) => {
if(err) return reject(err);
conn.query(sql, (err, results, fields) => {
conn.release()
if(err) return reject(err)
console.log(results)
resolve(results);
});
});
});
}
然后我通过以下方式调用它:
try{
const emailExisit = await sql.db(`SELECT email FROM users WHERE email = "${email}"`);
console.log(emailExisit);
if(emailExisit.length > 0) return res.status(422).send({"data": "", "code": "105", "message": "An account with given email already exists"});
}catch (err) {
console.log(err)
return res.status(500).send({"data": "", "code": "108", "message": `There seems to be an error contacting the database. Try again later <br> ${err}`});
}
但是,我的代码仍在继续,留下我的 emailExists
变量 undefined
(是的,它在 async function
中)
这是我使用 MySQL 和 Node.js 的配置。希望对你有用。
/config/mysql.js
const mysql = require('mysql2');
const pool = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
port: process.env.MYSQL_PORT,
database: process.env.MYSQL_DB_NAME,
});
const query = (query, args = []) =>
new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
return reject(err);
}
connection.query(query, args, (err, results) => {
connection.release();
if (err) {
return reject(err);
}
resolve(results);
});
});
});
module.exports = { query };
/index.js
const { query } = require('./mysql');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.get('/api/v1/sum', (req, res) => {
query('SELECT 1 + 1 as sum')
.then(results => {
res.json({ sum: results[0].sum });
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'error msg' });
});
});
// anther example with async
app.get('/api/v1/sum', async (req, res) => {
try {
const results = await query('SELECT 1 + 1 as sum');
res.json({ sum: results[0].sum });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'error msg' });
}
});
app.listen(3000);
我正在更改我的后端(从 Mongo 切换到 MySql)。我知道会抛出错误,因为 return 语句在我的 SQL 查询完成之前执行,然后当我的 sql 查询完成时,它会发送另一个 res.send
,因此我尝试将 mysql2
与 Promise 包装器一起使用,以便在我的 async
函数中的查询中使用 await
。
我有一个创建数据库连接的单独文件,因此我可以在整个 Nodejs 后端访问该连接:
const mysql = require('mysql2');
async function pool(){
const pool = await mysql.createPool({
host: "ip",
user: "username",
password: "password",
database: "db"
});
return pool
}
exports.getConnection = async function(callback) {
const currentPool = await pool();
currentPool.getConnection(function(err, conn) {
if(err) return callback(err);
callback(err,conn)
});
};
然后,创建一个遵循 async/await:
的查询sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
我也试过在查询中使用 await
:
await sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
我错过了什么?我还没有厌倦使用普通的 mysql
NPM 库并制作我自己的 promise 包装器...
新代码:
我更新了我的功能:
const mysql = require('mysql2');
const pool = mysql.createPool({
host: "ip",
user: "user",
password: "pass",
database: "db"
});
exports.db = (sql) => {
new Promise((resolve, reject) => {
pool.getConnection((err, conn) => {
if(err) return reject(err);
conn.query(sql, (err, results, fields) => {
conn.release()
if(err) return reject(err)
console.log(results)
resolve(results);
});
});
});
}
然后我通过以下方式调用它:
try{
const emailExisit = await sql.db(`SELECT email FROM users WHERE email = "${email}"`);
console.log(emailExisit);
if(emailExisit.length > 0) return res.status(422).send({"data": "", "code": "105", "message": "An account with given email already exists"});
}catch (err) {
console.log(err)
return res.status(500).send({"data": "", "code": "108", "message": `There seems to be an error contacting the database. Try again later <br> ${err}`});
}
但是,我的代码仍在继续,留下我的 emailExists
变量 undefined
(是的,它在 async function
中)
这是我使用 MySQL 和 Node.js 的配置。希望对你有用。
/config/mysql.js
const mysql = require('mysql2');
const pool = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
port: process.env.MYSQL_PORT,
database: process.env.MYSQL_DB_NAME,
});
const query = (query, args = []) =>
new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
return reject(err);
}
connection.query(query, args, (err, results) => {
connection.release();
if (err) {
return reject(err);
}
resolve(results);
});
});
});
module.exports = { query };
/index.js
const { query } = require('./mysql');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.get('/api/v1/sum', (req, res) => {
query('SELECT 1 + 1 as sum')
.then(results => {
res.json({ sum: results[0].sum });
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'error msg' });
});
});
// anther example with async
app.get('/api/v1/sum', async (req, res) => {
try {
const results = await query('SELECT 1 + 1 as sum');
res.json({ sum: results[0].sum });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'error msg' });
}
});
app.listen(3000);