He estado experimentando con un bot de Discord en Node.js. Me encontré con el problema de que todas las funciones no se ejecutan linealmente, sino de forma asíncrona. Logré introducir async/await para resolver este problema, pero ahora una de mis llamadas a funciones se ejecuta dos veces y no sé por qué (el comando !ec2-status se imprime dos veces en un chat determinado, aunque solo lo llamo una vez). La rutina que reacciona a un mensaje enviado es la siguiente:
// Event: Message client.on("messageCreate", msg => { // Extract metadata from message let msgServerID = msg.guildId; let msgChannelID = msg.channelId; let msgUserID = msg.author.id; let msgUsername = msg.author.username; // Select server and channel of current message let msgServer = client.guilds.cache.get(msgServerID); let msgChannel = msgServer.channels.cache.get(msgChannelID); // Command (!status): // Check AWS instance status if server is "Dev Server" if (msg.content === "!ec2-status") { const thingy = async () => { let instanceStatuses = await getEC2Status(); let statusText = "Instance Info: \n"; for (const instanceID in instanceStatuses) { statusText += `${instanceID}: ${instanceStatuses[instanceID]}\n`; } msg.reply(statusText); } thingy(); } });La función que se activa para obtener el estado de mis instancias EC2 (el objetivo del comando) es la siguiente:
// Function: Get the status of all EC2 instances const getEC2Status = async () => { // Variable to store the status of all instances let instanceStatuses = {}; // Retrieve instance information without previous permission check (DryRun = False) const results = await ec2.describeInstances({ DryRun: false }, (err, data) => { // Return an error if an error ocurrs if (err) { console.log("Retrieve Instance Info: Error\n", err.stack); } else { // Adds the info of each instance data.Reservations.forEach(reservation => { let instanceID = reservation.Instances[0].InstanceId; let status = reservation.Instances[0].State.Name; instanceStatuses[instanceID] = status; }); console.log("Retrieve Instance Info: Success\n", instanceStatuses); } }).promise(); return instanceStatuses }Me está costando entender async/await, por lo que ese puede ser el problema. Pero necesito que alguien me empuje en la dirección correcta. Ahora mismo, estoy un poco atascado.
Quizás los siguientes cambios ayuden:
client.on asíncrona, en lugar de solo la única función thingy thingy() que defina allí..promise() , pero no creo que tenga sentido esperar algo después de lo cual llamas a .promise() . Elimina el .promise() .En definitiva, así:
// Event: Message client.on("messageCreate", async (msg) => { // Extract metadata from message let msgServerID = msg.guildId; let msgChannelID = msg.channelId; let msgUserID = msg.author.id; let msgUsername = msg.author.username; // Select server and channel of current message let msgServer = client.guilds.cache.get(msgServerID); let msgChannel = msgServer.channels.cache.get(msgChannelID); // Command (!status): // Check AWS instance status if server is "Dev Server" if (msg.content === "!ec2-status") { let instanceStatuses = await getEC2Status(); let statusText = "Instance Info: \n"; for (const instanceID in instanceStatuses) { statusText += `${instanceID}: ${instanceStatuses[instanceID]}\n`; } msg.reply(statusText); } }); // Function: Get the status of all EC2 instances const getEC2Status = async () => { // Variable to store the status of all instances let instanceStatuses = {}; // Retrieve instance information without previous permission check (DryRun = False) const results = await ec2.describeInstances({ DryRun: false }, (err, data) => { // Return an error if an error ocurrs if (err) { console.log("Retrieve Instance Info: Error\n", err.stack); } else { // Adds the info of each instance data.Reservations.forEach(reservation => { let instanceID = reservation.Instances[0].InstanceId; let status = reservation.Instances[0].State.Name; instanceStatuses[instanceID] = status; }); console.log("Retrieve Instance Info: Success\n", instanceStatuses); } }); return instanceStatuses }Sin más información, creo que estos son los mejores primeros pasos.