简体   繁体   中英

Cannot read value from .txt file correctly

So, I've been creating Discord bot for my server. I created the command "join-chat". So it creates a 'request' and sends it to the service channel. Each request has an ID. The problem is that if I save ID as a variable, next time bot disconnects that number resets. So I decided to save the ID counter in file.
Here is the implementation:

    if (command === "join-chat") {
        let requestID = 0; //creating variable 'requestID'
        fs.readFile('./requestID.txt', 'utf-8', (err,data) => { //reading file 
            if (err) {
              return console.log(err);
            } 
            requestID = parseInt(data, 10); //and parsing string to integer
            //console.log('Read data succesfully!');
        })

        //requestID_num = requestID.replace(new RegExp('0'), '');

        const emb = new Discord.RichEmbed()
        .setTitle('New request')
        .setDescription('Request to add to chat')
        .addField('Who?', `**User ${msg.author.tag}**`)
        .addField('Which chat?', `**Chat: ${args[0]}**`)
        .setFooter('Request\'s ID: ' + requestID)
        .setColor('#fffb3a');
        requestID++;

        fs.writeFile('./requestID.txt', requestID.toString(), err =>{
            if (err) {
                return console.log(err);
            }
            //console.log('Wrote file succesfully!\n');
        })

        let chan = client.channels.get('567959560900313108');
        chan.send(emb);
    }

The problem now is that when I type in chat '.join-chat test', bot sends request, but ID is always 0, while in file it's 1.
Any suggestions how to solve this?

This is a common topic when dealing with asynchronous operation.

This reason that requestID is zero is because you are accessing it outside of the fs.readFile request which is an asynchronous operation. This means that the value of requestID is only 1 inside of the callback of the fs.readFile request and outside of it it is still 0.

To solve this, you have two options:

  1. Put the code that relies on requestID inside of the fs.readFile callback. This way you can be sure that requestID is always set to the latest value in the file you are reading it from.
...
fs.readFile('./requestID.txt', 'utf-8', (err, data) => {
    if(err) {
        return console.log(err);
    }

    requestID = parseInt(data, 10);

    const emb = new Discord.RichEmbed()
    ...
});
  1. Use a the synchronous version of reading a file (Note that this will block all further operation until request is finished). This lets you skip using callbacks but is not generally recommended.
...
const data = fs.readFileSync('./requestID.txt');

requestID = parseInt(data, 10);

const emb = new Discord.RichEmbed()
...

For more information on asynchronous operations check out some of the articles provided on MDN here .

As a challenge you can also try to convert the first way into a promise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM