#node.js
#node.js
Вопрос:
Я подключаюсь к узлу.JS с библиотекой, которая обеспечивает доступ к данным в стиле итератора:
next = log.get_next()
Я фактически хочу написать следующее:
while (next = log.get_next()) {
console.log(next);
}
и перенаправление stdout
в файл (например node log.js > log.txt
). Это хорошо работает для небольших журналов, но для больших партий выходной файл пуст, и использование моей памяти зашкаливает.
Похоже, я не до конца понимаю ввод-вывод в node, поскольку простой бесконечный цикл, который записывает строку на консоль, также демонстрирует такое же поведение.
Было бы здорово дать несколько советов о том, как выполнить эту задачу. Спасибо.
Ответ №1:
Класс writeStream буферизует ввод-вывод, и если вы никогда не предоставляете поток, записи в очереди никогда не обслуживаются. Наилучший подход заключается в записи разумного объема данных, затем подождите, пока буфер очистится, прежде чем записывать снова. Класс writeStream выдает событие ‘drain’, которое сообщает вам, когда буфер был полностью очищен. Вот пример:
var os = require('os');
process.stdout.on('drain', function(){
dump();
});
function dump(){
for (var i=0; i<10000; i )
console.log('xxxx');
console.error(os.freemem());
}
dump();
Если вы запускаете как:
node testbuffer > output
вы увидите, что файл периодически увеличивается, а память достигает устойчивого состояния.
Ответ №2:
Библиотека, с которой вы взаимодействуете, должна принимать обратный вызов. Node.js разработан, чтобы быть неблокирующим. Я думаю, что, возможно, console.log
продолжает возвращать управление циклу (и log.get_next()
) перед отправкой выходных данных.
Если модуль был переписан, чтобы заставить get_next поддерживать обратный вызов, улучшенный код может быть таким:
var log_next = function() {
console.log(next);
log.get_next(log_next);
};
log.get_next(log_next);
(Существуют библиотеки и шаблоны, которые могли бы сделать этот код красивее.)
Если код только синхронный и должен оставаться таким, какой он есть, вызов setTimeout с 0 или другим небольшим числом может предотвратить блокировку всего процесса.
var log_next = function() {
console.log(log.get_next());
setTimeout(log_next, 0);
};
log_next();