Чтение и обработка файлов не завершаются перед попыткой записи в новый файл. Обещание связано

#javascript #file-processing

#javascript #обработка файлов

Вопрос:

Действительно борется здесь и просто потерян на этом этапе. Обещания КАЖУТСЯ простыми, пока я не попытаюсь их использовать. Я предоставляю свой упрощенный код, который не содержит попыток обещания упростить работу. Я вернулся к этому после нескольких месяцев просто отказа. Этот небольшой скрипт строчно считывает файлы в каталоге и добавляет все эти строки в массив. Как только это закончится, я хочу записать все эти файлы в новый файл.
Проблема, конечно, в том, что writeAllLinesToFile вызывается до того, как массив allTheLines заполнится строками, прочитанными из файлов каталогов. Массив полностью пуст, и ничего из прочитанных файлов не записывается в новый файл. Я сделал много попыток с этим и просто запутал свой реальный код в этой попытке. Может кто-нибудь подтолкнуть меня к этому горбу?

 var allTheLines = [];

function processFile(inputFile) {
    var fs = require('fs');
    var readline = require('readline');
    var instream = fs.createReadStream(inputFile);
    var outstream = new (require('stream'))();
    var rl = readline.createInterface(instream, outstream);

    // when you get a line, do this 
    rl.on('line', function (line) {
        // console.log("pushing: ", line);
        allTheLines.push(line);
    });

    // when there are no more lines do this
    rl.on('close', function (line) {
        console.log('...end of a file');
    });
}

function writeAllLinesToFile() {
    var fs = require('fs');
    for (var i = 0; i < allTheLines.length; i  ) {
        console.log("line: : ", allTheLines[i]);
        fs.appendFile('./allTheLines.html', allTheLines[i]   'n', function (err) {
            if (err) throw err;
        });
    };
    console.log("Done writing.");
}

// ***************************************
// Execution Starts Here
// ***************************************
var fs = require('fs');
fs.readdir('./filesToRead', (err, files) => {
    for (var i = 0; i < files.length; i  ) {
        processFile('./filesToRead/'   files[i]);
        console.log('file#: ', i);
    };
    console.log('Done processing files.');
    writeAllLinesToFile();
});
  

Ответ №1:

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

Я считаю, что самое главное, что вы забыли, это то, что когда мы используем источники событий, мы должны знать, что они являются асинхронным кодом, а не синхронным, поэтому writeAllLinesToFile имел пустой массив, потому что он был вызван до того, как rl.on(‘line’, ….) выполнил свою работу, и это сложнонаверстать упущенное 😉

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

 var fs = require('fs');
var readline = require('readline');
var path = require('path');
var stream = require('stream');

function processFile(inputFile) {
    var instream = fs.createReadStream(inputFile);
    var outstream = new stream();
    var rl = readline.createInterface(instream, outstream);
    var allTheLines = [];

    // when you get a line, do this 
    rl.on('line', function (line) {
        allTheLines.push(line);
    }).on('close', function () {
        writeAllLinesToFile(allTheLines);
    });
}

function writeAllLinesToFile(lines) {
    for (var i = 0; i < lines.length; i  ) {
        fs.appendFile(path.join(__dirname, 'allTheLines.html'), lines[i]   'n', function (err) {
            if (err) throw err;
        });
    };
  
    console.log("Done writing.");
}

// ***************************************
// Execution Starts Here
// ***************************************

fs.readdir(path.join(__dirname, 'filesToRead'), (err, files) => {
  if (err) throw err;

    for (var i = 0; i < files.length; i  ) {
        processFile(path.join(__dirname, 'filesToRead', files[i]));
    };

    console.log('Done processing files.');
});
  

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

1. Ясин, спасибо за ваше время, к сожалению, похоже, что я слишком сильно упростил проблему в своем сообщении. Ваше решение отлично подходит для вопроса, который я задал, но я кое-что забыл. В верхней части моего скрипта я объявляю массив, и когда я обрабатываю каждый файл, я обновляю объекты в этом массиве на основе соответствующих строк в файле, который я читаю. Итак, я не могу добавлять к файлу после окончания каждого обрабатываемого файла. Мне нужно отложить запись до тех пор, пока я не обработаю все файлы. Есть ли быстрая настройка для этого или это открывает совершенно новую банку с червями?