#javascript #mysql
Вопрос:
Я пытаюсь преобразовать соединение MySQL из promise в asycn. Пока у меня есть следующая настройка:
const mysql = require("mysql");
const pool = mysql.createPool({
connectionLimit: 10,
password: "",
user: "root",
database: "usersdb",
host: "localhost",
port: "3306",
});
let usersDB = {};
usersDB.all = () => {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users", (err, results) => {
if (err) {
return reject(err);
}
return resolve(results);
});
});
};
usersDB.one = (id) => {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users WHERE id = ?", [id], (err, results) => {
if (err) {
return reject(err);
}
return resolve(results[0]);
});
});
};
module.exports = usersDB;
Есть ли способ преобразовать эти коды:
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM users", (err, results) => {
if (err) {
return reject(err);
}
return resolve(results);
});
чтобы асинхронно ожидать и сделать код более сжатым или сжатым?
ОБНОВЛЕНИЕ: на моем маршрутизаторе у меня есть эти коды:
const router = express.Router();
router.get("/", async (req, res) => {
try {
let results = await db.all();
res.json(results);
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
router.get("/:id", async (req, res) => {
try {
let results = await db.one(req.params.id);
res.json(results);
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
Так что это просто нормально, вызывать асинхронное ожидание дважды?
Комментарии:
1. Было бы проще использовать библиотеку с интерфейсом promise, такую как
promise-mysql
илиmysql2
.
Ответ №1:
Вы можете преобразовать любую функцию обратного вызова в promise с помощью util.promisify
const util = require('util')
// ....
const query = util.promisify(pool.query)
// ... inside some async function
const users = await query("SELECT * FROM users;")
// or promise style
query("SELECT * FROM users;")
.then((users) => {
console.log(users)
})
.catch(console.error)
Ответ №2:
usersDB.one = (id) => {
try {
const users = pool.query("SELECT * FROM users WHERE id = ?", [id]);
return users;
} catch (e) {
throw e;
}
};
Или проще говоря,
usersDB.one = (id) => pool.query("SELECT * FROM users WHERE id = ?", [id]);
Комментарии:
1. Но все это при условии, что клиент mysql операционной системы даже имеет интерфейс promise. Ошибка «ожидание» не влияет на тип этого выражения.ts(80007)» предполагает, что это не так, поэтому в моем самом первом комментарии говорилось, что, вероятно, все обещания бессмысленны, пока операция не изменится на клиента, у которого вообще есть интерфейс обещаний!
2. Я не могу вносить правки, потому что это изменило бы весь смысл ответа, на мой взгляд, он должен быть «используйте другую библиотеку, например
promise-mysql
«. С самого начала я пытался объяснить, что проблема не в ожидании, а в том, что пул. запрос даже не возвращает обещание-вот что вызвало предупреждение TS…3. но эта библиотека «mysql» также имеет многообещающие перспективы (см.: tabnine.com/code/javascript/functions/mysql/Pool/… )
4. Нет, код, который вы связали сначала вручную, обещает функцию: github.com/antoniosarosi/Contacts-App-Nodejs/blob/… — что также является решением, но я бы не рекомендовал его, потому что другие функции все равно не будут использовать обещания, и легко забыть, что происходит именно это, лучше использовать то, что изначально предназначено для обещаний.
Ответ №3:
Что вы хотите сделать, так это пообещать вызов БД. Вы можете достичь этого путем факторизации :
const mysql = require("mysql");
const pool = mysql.createPool({
connectionLimit: 10,
password: "",
user: "root",
database: "usersdb",
host: "localhost",
port: "3306",
});
function promisify(...args){
return new Promise((resolve, reject) => {
pool.query(...args, (err, result) => {
if(err) reject(err);
resolve(result);
});
});
}
let usersDB = {};
//Then you can call it this way :
usersDB.all = async () => {
return await promisify("SELECT * FROM users");
//Note that you can avoid to await there.
};
usersDB.one = async (id) => {
return await promisify("SELECT * FROM users WHERE id = ?", [id]);
};
module.exports = usersDB;