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