Не могу вернуться из функции

Итак, что я пытаюсь сделать, это создать функцию, использовать mysql (неважно, как, но я нашел для нее npm, поэтому пока использую его.), чтобы получить информацию из моей базы данных, а затем передать ее json. Он отлично работает, пока console.info() находится в нужном месте, но я должен вернуть его, поэтому мне нужно переместить его ниже. Но когда я это сделаю, он не будет отображаться в моем другом файле, который мне нужен.

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

get_ally_online_players: function (guild) {

  con.query("SELECT * FROM user_dbs WHERE guild='"+ guild +"'", function (err, result, fields) {

    var con2 = mysql.createConnection({
        host: result[0].host,
        user: result[0].username,
        password: result[0].password,
        database: result[0].database
    })


    con2.connect()

    con2.query("SELECT * FROM characters WHERE online='1' AND race=1 OR race=3 OR race=4 OR race=7 OR race=11", function (err, result, fields) {
      allycount = 0
      console.dir(result)
      result.forEach(function(result) {
        allycount = allycount+1
      })
      return allycount

    });
    con2.end()
  });
}

Вот где я пытаюсь это сделать:

        if (recieved.content === "!status")
        {

            var horde_players
            var ally_players
            horde_players == guilddb.get_horde_online_players("585919060722712670")
            ally_players == guilddb.get_ally_online_players("585919060722712670")
            console.info(guilddb.test())
            //console.info(ally_players)
            recieved.channel.send(ally_players + " : " + horde_players)
        }

Я пробовал так много вещей... Я также читал, что вы должны использовать обратные вызовы, так как это, по-видимому, происходит слишком быстро, как будто он не может запрашивать раньше... Однако я хотел бы держаться подальше от обратного вызова, поскольку он кажется хлопотным внутри сценария. Но если уж очень надо, то так тому и быть. Он возвращается с «неопределенным» кстати. Я также пытался использовать промисы вместо этого и помещал функцию setTimeout и т.д.

Совет: вместо x=1 OR x=2 OR x=3 используйте x IN (1,2,3).

tadman 07.06.2019 19:48
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
1
38
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш запрос является асинхронным, поэтому функция неявно вернет неопределенный до завершения запроса.

Поэтому вам нужно будет использовать обратные вызовы или промисы.

Вы можете использовать такие обратные вызовы:

// Accept a callback function as an argument
get_ally_online_players: function (guild, callback) {

  con.query("SELECT * FROM user_dbs WHERE guild='"+ guild +"'", function (err, result, fields) {

    var con2 = mysql.createConnection({
      host: result[0].host,
      user: result[0].username,
      password: result[0].password,
      database: result[0].database
    })

    con2.connect()

    con2.query("SELECT * FROM characters WHERE online='1' AND race=1 OR race=3 OR race=4 OR race=7 OR race=11", function (err, result, fields) {
      allycount = 0
      console.dir(result)
      result.forEach(function(result) {
         allycount = allycount+1
      })

      // Pass the result to the callback function
      callback(allycount)
    })

    con2.end()
  })
}

...а затем передайте функцию обратного вызова в get_ally_online_players, которая будет получать данные, когда они будут готовы:

if (recieved.content === "!status") {
  var horde_players
  var ally_players
  horde_players = guilddb.get_horde_online_players("585919060722712670")

  // Pass a callback function that will receive the data when ready
  guilddb.get_ally_online_players("585919060722712670", function(ally_players) {
    console.info(ally_players)
    recieved.channel.send(ally_players + " : " + horde_players)
  })

}

Надеюсь, это поможет.

Ответ принят как подходящий

Прежде всего, извините за мой английский.

На самом деле вы совершаете некоторые ошибки.

Вы совершили ошибку, присвоив значения значениям horde_players и ally_players.

if (recieved.content === "!status") {
    var horde_players
    var ally_players
    horde_players = guilddb.get_horde_online_players("585919060722712670")
    ally_players = guilddb.get_ally_online_players("585919060722712670")
    console.info(guilddb.test())
    //console.info(ally_players)
    recieved.channel.send(ally_players + " : " + horde_players)
}

С (==) вы сравниваете значения, а не устанавливаете.

Теперь поговорим об асинхронных операциях.

Я подготовил пример. Это похоже на то, как в вашем случае вы пытаетесь запустить две асинхронные операции, которые могут завершиться в разное время, но вам нужно, чтобы обе они были завершены, прежде чем запускать что-то еще. Попробуйте запустить его:

function async1(id, callback) {
    setTimeout(function() {
        callback('The user with ' + id + ' is called Sergio');
    }, 6000);
}

function async2(id, callback) {
    setTimeout(function() {
        callback('The user with ' + id + ' is called Jack');
    }, 2000);
}

var result1;
var result2;

async1(1, function(result) {
    result1 = result;
});

async2(2, function(result) {
    result2 = result;
});
console.info('Finished result: ' + result1 + result2); // Finished result: undefined undefined

Готовый результат был запущен до завершения обеих асинхронных операций. Плохо...

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

function async1(id, callback) {
    setTimeout(function() {
        callback('The user with ' + id + ' is called Sergio');
    }, 6000);
}

function async2(id, callback) {
    setTimeout(function() {
        callback('The user with ' + id + ' is called Jack');
    }, 2000);
}

var result1;
var result2;

async1(1, function(result) {
    result1 = result;

    async2(2, function(result) {
        result2 = result;
        console.info('Finished result: ' + result1 + result2); // 'Finished result: The user with 1 is called SergioThe user with 2 is called Jack
    });
});

Для вашего случая это было бы моим решением. Возможно, я бы улучшил больше вещей, таких как использование const-let и функций ES6 (асинхронное ожидание, функции стрелок...), передача параметров коннекторов базы данных через параметры... но, возможно, теперь вам легче понять

var guilddb = {
    get_horde_online_players: function(guild, callback) {
        callback('Implement me!');
    },
    get_ally_online_players: function(guild, callback) {
        con.query("SELECT * FROM user_dbs WHERE guild='" + guild + "'", function (err, result, fields) {
            var con2 = mysql.createConnection({
                host: result[0].host,
                user: result[0].username,
                password: result[0].password,
                database: result[0].database
            });

            con2.connect();

            con2.query("SELECT * FROM characters WHERE online='1' AND race=1 OR race=3 OR race=4 OR race=7 OR race=11", function (err, result, fields) {
                var allycount = 0;
                console.dir(result);
                result.forEach(function(result) {
                    allycount = allycount+1
                });

                con2.end();
                callback(allycount);
            });
        });
    }
}

if (recieved.content === "!status") {
    guilddb.get_horde_online_players("585919060722712670", function(result) {
        var horde_players = result;

        guilddb.get_ally_online_players("585919060722712670", function(result) {
            var ally_players = result;
            console.info(guilddb.test());
            console.info(ally_players);
            recieved.channel.send(ally_players + " : " + horde_players);
        });
    });
}

Надеюсь, поможет.

Еще одна вещь, которую стоит сделать, — это свернуть объявление var и присваивание в одну строку, чтобы сделать его более понятным.

tadman 07.06.2019 19:47

Другие вопросы по теме