4

Имеется метод

function user_info (login) {

    var info;

    this.pool.getConnection(function(err, connection) {
        if (err) throw err;
        connection.query('SELECT * FROM user WHERE login = ?', [login], function (error, results, fields) {
            info = results;
            connection.release();

        });
    });

    return info;
}

В данном примере в info получаю undefined, тогда как в results записан объект(проверял через дебаг)

Мне нужно вернуть методом user_info объект results, как это сделать? Пробовал почти всё кроме промисов

  • Возможный дубликат https://ru.stackoverflow.com/questions/554290/%D0%9A%D0%B0%D0%BA-%D0%B2%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8%D0%B7-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F-%D0%B8%D0%BB%D0%B8-%D0%B8%D0%B7-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8-%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0-%D0%98%D0%BB%D0%B8-%D1%85%D0%BE%D1%82%D1%8F-%D0%B1%D1%8B-%D0%B4%D0%BE%D0%B6?noredirect=1&lq=1 – Stepan Kasyanenko Aug 21 '18 at 04:13

4 Answers4

2

JS однопоточный, но не надо пытаться делать все по порядку:

//Плохой подход для JS

var данные;
данные = запрашиваем_данные_из_далека();
обрабатываем_данные(данные);

вместо этого на JS делается так:

//Хороший подход для JS

обрабатываем_данные(данные){

}

запрашиваем_данные_из_далека(обрабатываем_данные);

То есть не надо делать все при первом проходе (ждать данные). Указал функции для обратного вызова, вышел и ждешь.

В вашем случае можно использовать Promise и async/await, но лучше, то что выполняется после:

var data = user_info("Admin");

вынести в функцию обратного вызова (callback).

Максим
  • 2,324
2
function user_info (login, callback) {
  this.pool.getConnection(function(err, connection) {
    if (err) throw err;
    connection.query('SELECT * FROM user WHERE login = ?', [login], function (error, results, fields) {
      connection.release();
      callback(results);
    });
  });
}

db.user_info(cookies.login, function(info){ 
  /* code that uses user info */ 
});
1

Предлагаю вот такой вариант:

import mysql from 'promise-mysql';

var mysqlConfig = {
    ...
};

async function user_info (login) {
    try {
        var connection = await mysql.createConnection(mysqlConfig);
        var info = await connection.query(`SELECT * FROM user WHERE login="${ login }";`);
        connection.end();
        return info;
    } catch (error) {
        throw error;
    }
}

Кстати, сохранил Ваш стиль, но заканчивайте уже использовать var)

muturgan
  • 1,246
  • Больше примеров написано здесь: www.npmjs.com/package/promise-mysql. Рекомендую использовать сразу этот пакет вместо mysql - это уже обертка с промисами. Я правда использовал async/await синтаксис т.к. считаю его более чистым - в примерах разобрано с then. – muturgan Aug 21 '18 at 06:15
  • Это сработало. Так же вариант от Igor который предложил callback(results); – Андрей Aug 21 '18 at 06:28
1

Кстати, если максимально использовать Ваш код, предлагаю такой вариант:

function user_info (login) {

    var info = this.pool.getConnection(function(err, connection) {
        if (err) throw err;
        connection.query('SELECT * FROM user WHERE login = ?', [login], function (error, results, fields) {
            if (error) throw error; // здесь то тоже ошибку стоит обработать
            connection.release();
            return results; // кстати, т.к. мы то знаем, что у нас только 1 пользователь с таким логином,
                            // я бы сразу возвращал results[0]
        });
    });

    return info;
}
muturgan
  • 1,246
  • блин, чувак, конечно может. но ты если вернешь просто results, ты в том месте, где используешь результат вызова функции user_info, все равно будешь проверять что там лежит в "что-вернула-функция"[0] и если undefined то сказать пользователю что такого логина нет, а если вменяемое значение то пусть заходит. а возвращая results[0] у тебя код обработки результата вызова user_info становиться чуть более читаемым. но возвращать results[0] конечно совсем не обязательно -дело вкуса. поэтому и закомментировано. – muturgan Aug 21 '18 at 07:27
  • return results; - куда это, интересно, вернется? –  Aug 21 '18 at 20:48
  • var info = this.pool.getConnection(function(err, connection) { ... return results;}); вот в переменную info и запишется – muturgan Aug 22 '18 at 04:18
  • если не видишь смысла сохранять промежуточный результат в info, можно и так написать: function user_info (login) { return this.pool.getConnection(function(err, connection) { ... return results;}); } – muturgan Aug 22 '18 at 04:22
  • @muturgan Мы же, вроде, все согласны, что оба колбэка выполняются асинхронно. Присвоение var info = выполнится гораздо раньше, чем return results;. –  Aug 22 '18 at 13:24
  • @Igor один вопрос. Вы тестировали предложенный код? Я тестировал. – muturgan Aug 22 '18 at 16:20
  • @muturgan Вы тестировали неправильно. В переменной info не может оказаться значение results. В первую очередь потому, что this.pool.getConnection не возвращает results. –  Aug 22 '18 at 16:25