Преобразуйте обещание в асинхронное

#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;