Как записать значение в переменную во время выполнения асинхронной функции JavaScript [дубликат]

145
13 ноября 2018, 21:50

На данный вопрос уже ответили:

  • Как вернуть значение из события или из функции обратного вызова? Или хотя бы дождаться их окончания 3 ответа

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

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, как это сделать? Пробовал почти всё кроме промисов

Answer 1
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 */ 
});
Answer 2

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

//Плохой подход для JS
var данные;
данные = запрашиваем_данные_из_далека();
обрабатываем_данные(данные);

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

//Хороший подход для JS
обрабатываем_данные(данные){
}
запрашиваем_данные_из_далека(обрабатываем_данные);

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

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

var data = user_info("Admin");

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

Answer 3

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

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)

Answer 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) {
            if (error) throw error; // здесь то тоже ошибку стоит обработать
            connection.release();
            return results; // кстати, т.к. мы то знаем, что у нас только 1 пользователь с таким логином,
                            // я бы сразу возвращал results[0]
        });
    });
    return info;
}
READ ALSO
vue.js Поиск по элементам

vue.js Поиск по элементам

Всем привет,не получается реализовать поиск по элементам,данные получаю из api,подскажите как его можно сделатьВот код элемента,по которому...

146
Парсинг первого элемента списка в dom

Парсинг первого элемента списка в dom

Есть разметка html на сайте:

179
undefined или ? typescript

undefined или ? typescript

Вопрос больше по красоте кодаКак лучше написать

149
Как отобразить mini-карту с помощью JS?

Как отобразить mini-карту с помощью JS?

С помощью Конструктора карт я сгенирировал код

163