1

Допустим я использую node-mysql из npm для выполнения sql-запросов. С появлением node 7 и поддержки ней async/await, хотелось бы понять, как можно применить это для выполнения sql запросов? Задача в целом написать класс-обертку для node-mysql, чтобы потом можно было делать нечто вроде:

let data = new MySqlWrapper().select(query);

ну и в итоге в data мы имеем результат выполнения запроса.

Подскажите как можно реализовать это на данном примере:

(async () => {
            let getData = async ()=> {
                db.query(`select * from users`,null,(err,data) =>{
                    console.log('ok');
                    return data;
                });
            };

            var res = await getData();
            //нужно чтобы в res пришли данные запроса
})();
sanu
  • 2,575

1 Answers1

5

Конструкции async/await отлично работают не только с асинхронными функциями, но и с Обещаниями (Promises). Например, код

let select = function(query) {
    return new Promise(function(resolve, reject) {
        setTimeout(() => {resolve(`${query}s`)}, 1000);
    });
};

async function run() {
    let foos = await select('foo');
    let bars = await select('bar');

    console.log(`${foos} + ${bars}`);
}

run();

выведет сообщение foos + bars через две секунды.

Эта маленькая хитрость позволит вам решить вашу проблему "малой кровью". Вы можете использовать одну из существующих библиотек, чтобы заставить ваши методы возвращать Обещания. Приведу пример того, это можно сделать используя Bluebird:

let bluebird = require('bluebird'),
    asyncWrapper = (f, ctx) => bluebird.promisify(f, {context: ctx});

let mysql = new MySql();
let data = await asyncWrapper(mysql.select, mysql)(query);

При желании, вы можете написать класс, содержащий в себе новый, асинхронный API. Но эта задача тривиальна и я оставлю ее для вас :)

Dmitriy Simushev
  • 17,999
  • 5
  • 49
  • 85
  • В вашем 1-м примере, если допустить что после run(); в самом конце будет какой-то код, то этот код не будет выполняться пока не отработает run (2 секунды)? – sanu Nov 08 '16 at 15:14
  • @sanu0074, нет, но этого и не должно происходить. Конструкция await работает только внутри асинхронных функций (с маркером async). Поэтому, если вам нужно выполнить что-то строго подряд, помещайте эти команды в в run и снабжайте их вызовы маркером await – Dmitriy Simushev Nov 08 '16 at 15:18
  • @sanu0074 мы же с вами уже обсуждали async/await вот тут. – Dmitriy Simushev Nov 08 '16 at 15:22
  • я прочитал все, так и не пойму как заставить работать эту конструкцию, я пример в вопросе привел, можете подсказать? – sanu Nov 08 '16 at 22:42
  • @sanu0074 Перепишите весь этот ужас внутри стрелочной функции так, чтобы он возвращал промис. Пример того, как с минимальным трудозатратами сконвертировать функцию, принимающую колбэк в функцию возвращающую промис я привел в ответе. – Dmitriy Simushev Nov 08 '16 at 23:02
  • спасибо) с промисом заработало – sanu Nov 09 '16 at 21:02