Как прочитать файл (синхронно?) в цикле while в javascript (Discord.js)?

#javascript #while-loop #discord.js #synchronization #filereader

Вопрос:

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

По сути, я создаю код, который выполняется в цикле while, где мне нужно затем прочитать файл в этом цикле while, и кажется, что чтение файла в коде просто останавливает цикл while от завершения. Я все еще довольно новичок в javascript, так что, вероятно, это простое решение.

До сих пор я пытался изменить свою функцию JsonReader на синхронизацию (readFileSync), и это просто остановило код, прежде чем он почти ничего не сделал. (теперь это то, что представляет собой текущий код) Я также попытался создать вторую функцию для синхронного чтения файлов, которые мне нужны, и это, похоже, тоже не сработало. Я даже не уверен, связано ли это с синхронностью

Мой Код:

 module.exports = {
    name: 'xprun',
    description: "runs the xp handler",
    execute(message) {
 
        const name = message.author.username;
        const server = message.guild.id;
 
        const fs = require('fs');
 
        function jsonReader(filePath, cb) {
            fs.readFileSync(filePath, 'utf-8', (err, fileData) => {
                if (err) {
                    return cb amp;amp; cb(err);
                }
                try {
                    const object = JSON.parse(fileData);
                    return cb amp;amp; cb(null, object);
                } catch (err) {
                    return cb amp;amp; cb(err);
                }
            });
        }
 
        console.log('Starting the loop...'); //
        
        var run = true;
        var i = 0;
 
        while (run == true) {
            i  
 
            console.log('Running the loop...'); // Loop stops and re-runs here
 
            // read #1
 
                jsonReader(`./userData/rank/${server}_server/1.json`, (err, data) => {
 
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(data.id); //
                    }
 
            // read #2
 
                jsonReader(`./userData/xp/${server}_server/${name}_xp.json`, (err, data) => {
 
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(data.rank); //
                    }
 
                    console.log('The loop was completed'); //
                    
                    if (i >= 5) {
                        run = false;
                    }
 
                }); // end read #1
 
            }); // end read #2
 
        } // end while
 
        console.log('The loop was ended'); //
 
    } // end execute
 
} // end
 

Комментарии:

1. Вместо текущего кода в вашем вопросе, можете ли вы предоставить код для вашей попытки использовать readFileSync его ? Это, скорее всего, ближе к ответу, чем текущий предоставленный код. Кроме того, есть ли какие-либо ошибки в консоли (например, когда код «останавливается», как вы упомянули)? Можете ли вы также сократить этот код, чтобы предоставлялся только соответствующий код? Нам не нужно видеть остальную часть кода, это просто затрудняет чтение вашего кода. Просто включите jsonReader и просто соответствующие части while цикла.

2. Конечно! Пожалуйста, обратите внимание, что считываемые файлы действительно существуют и могут быть прочитаны, когда я не использую свой код вне цикла while. Мне нужно будет отредактировать свой исходный вопрос, чтобы он все еще соответствовал коду, поэтому, пожалуйста, посмотрите на него, чтобы увидеть его.

3. В коде нет ошибки, например, он не выводит ошибку, а просто продолжает выводить «Запуск цикла…» и никогда не останавливается

4. readFileSync не отвечает на обратный звонок.

Ответ №1:

Как упоминал @CherryDT в комментариях, readFileSync не принимает обратный вызов. Поскольку readFileSync он синхронный, ему не нужен обратный вызов; readFile принимает обратный вызов только потому, что он асинхронный, потому что ему нужно подождать, пока он прочитает файл, прежде чем вызывать код в обратном вызове. Синхронному методу не нужно ждать таким образом, поэтому вы можете переместить код обратного вызова из обратного вызова следующим образом:

 function jsonReader(filePath, cb) {
    try {
        const fileData = fs.readFileSync(filePath, 'utf-8');
        const object = JSON.parse(fileData);
        return cb amp;amp; cb(null, object);
    } catch (err) {
        return cb amp;amp; cb(err);
    }
}
 

Причина, по которой ваш цикл выполнялся бесконечно, заключалась в том, что вы установили run значение false только в своем cb методе обратного вызова, но поскольку readFileSync он не принимает обратный вызов, ваш обратный вызов никогда не выполнялся. С помощью приведенного выше кода ваш обратный вызов теперь должен выполняться, и цикл больше не должен выполняться бесконечно (если только в ваших обратных вызовах нет других проблем).