0
module.exports = {
    name: "help",
    execute(msg, args){
        const fs = require("fs");
        const commandFiles = fs.readdirSync("./commands/").filter(file => file.endsWith(".js"));
        for (const file of commandFiles){
            const name = file.slice(0, -3);
            const descriptionFileName = name.concat(".desc");
            const descriptionFile = `./commands/${descriptionFileName}`;
            var output = "Help:";
            fs.readFile(descriptionFile, function(err, data){
                const helpLine = name.concat(" - ",data.toString());
                output = output + "\n" + helpLine
            });
            msg.channel.send(output);
        }
    }
}

Expected output: help - description ping - description

Output: Help: Help:

Any idea why that happens? Im new at coding and very new at js.

  • fs.readFile() uses an asynchronous function/callback, meaning that entire block does not execute in the sequence you are expecting. https://stackoverflow.com/questions/10058814/get-data-from-fs-readfile – Tank Jul 28 '20 at 14:33

1 Answers1

0

you didn't get the expected result because readFile(file, cb) reads a file asynchronously. This means that it just schedule a callback cb to be executed once the I/O operation has been completed. However the following code:

msg.channel.send(output)

will be executed synchronously so the output will remain with the initial value.

One way to handle this could be with promises, here a partial example based on your code:

module.exports = {
  name: 'help',
  async execute(msg, args) {
    const { readFile, readdir } = require('fs').promises;
    const fs = require('fs');
    const commandFiles = await readdir('./commands/').filter((file) => file.endsWith('.js'));
    const promises = [];

    for (const file of commandFiles) {
      promises.push(
        fs.readFile(file)
      )
    }

    const results = await Promise.all(promises);

    // manipulate results as you want
    msg.channel.send(results);
  },
};

Note that because of the async prefix the exported execute function you need to handle a promise in the consumer of this module

Another approach could be to use a fully parallel control flow pattern

Some references:

penguintheorem
  • 321
  • 1
  • 4