Node.js console.log - чи можна оновити рядок, а не створювати новий?


83

У моїй node.jsпрограмі є багато журналів консолі, які мені важливо побачити (це досить великий додаток, тому він працює довгий час, і я повинен знати, що справа все ще прогресує), але я закінчую тисячами рядків журнали консолі.

Чи можна якось зробити a, console.updateякий стирає / замінює рядок консолі, а не створює новий рядок?


1
Чому б не записати у файл журналу, який ви можете контролювати чи шукати?
Нельсон,

1
Я можу зробити це досить легко в PowerShell, але більше того, у мене написано близько 5000 рядків консолі, які можуть легко зайняти 10 рядків (більшість із них - це лише дзвінки, які дають мені зрозуміти, що справа прогресує, що важливо, як Додаток працює приблизно 20 хвилин, і мені потрібен відгук про те, чи щось не працює або все ще працює).
JVG

Це відповідає на ваше запитання? Як стерти символи, надруковані на консолі
Wex,

Відповіді:


127

Спробуйте пограти з методами process.stdout замість цього на консолі:

process.stdout.write("Hello, World");
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write("\n"); // end the line

10
Помилка типу: process.stdout.clearLine не є функцією. Неможливо запустити веб-шторм, якщо хтось ще стикається з цим.
Тревор,

@TrevorD мій підхід до цього полягав у тому, щоб додати webstorm=trueпараметри програми у конфігурації вузла webstorm та перевірити, чи process.argv.find(x => x.startsWith('webstorm=true')використовується ця відповідь
Луїс Едуардо

1
@Luiz Eduardo Чи не простіше було б просто обернутися if (process.stdout.clearLine) { process.stdout.clearLine() }?
Тревор,

Хороший улов! Я чомусь навіть не думав про це. Оскільки я створював невеликий простий інструмент для запуску в консолі, я все-таки не дав його докладно, але обов’язково зміню, дякую!
Луїс Едуардо,

Я б зробив це: node -e "for(let i=1;i<=1000;i++){process.stdout.write('Hello, World'); if(i<10)process.stdout.clearLine(); process.stdout.cursorTo(0);}"абоnode -e "for(let i=1;i<=1000;i++){process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write('hello, world')}"
Цербер

55

Після відповіді @ michelek ви можете скористатися такою функцією:

function printProgress(progress){
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(progress + '%');
}

1
При використанні цього з циклом for воно мерехтить, чи є спосіб це виправити?
Ank i zle

1
щоб виправити мерехтіння, позбутисяprocess.stdout.clearLine()
decoder7283

я зрозумів, що додавання цього до великого циклу значно збільшує час обчислення. Наприклад, я запускаю випадкові спроби 100mil і присвоюю змінним. Це має зайняти 3 секунди. за допомогою цієї функції. це займає
Mj Jameel

не зважай на мій вищезазначений коментар. Я думаю, усі журнали консолі коштують багато. і оскільки я намагався надрукувати прогрес у відсотках, мені довелося написати функцію, яка друкує лише через певні інтервали, наприклад 1% 2% тощо
Mj Jameel

21

Звичайно, ви можете зробити це за допомогою модуля, який я допоміг створити: fknsrs / jetty

Встановити через

npm install jetty

Ось приклад використання

// Yeah, Jetty!
var Jetty = require("jetty");

// Create a new Jetty object. This is a through stream with some additional
// methods on it. Additionally, connect it to process.stdout
var jetty = new Jetty(process.stdout);

// Clear the screen
jetty.clear();

// write something
jetty.text("hello world");
jetty.moveTo([0,0]);
jetty.text("hello panda");

Причал не надто корисний, якщо його використовувати самостійно. Це набагато ефективніше, коли ви будуєте трохи абстракції на ньому, щоб зробити ваші дзвінки на пристані менш багатослівними.


3
Я підтримав це рішення через обмежувальну ліцензію на цей пакет.
mmmeff

17
Це стандартна ліцензія BSD із 3 положеннями . Досить погана причина для голосування проти, imo.
Дякую,

6
@mmmeff, якщо ви вважаєте, що ліцензія BSD із 3 положення є обмежувальною, я боюся, що ви помрете, коли почуєте про ліцензії GPL та AGPL.
Майкл Пфафф,

15

Щоб написати частковий рядок.

process.stdout.write("text");
process.stdout.write("more");
process.stdout.write("\n"); // end the line

Якщо обсяг випуску є справжньою проблемою, ви, мабуть, переосмислите свою реєстрацію. Ви можете використовувати систему реєстрації, яка дозволяє селективне ведення журналу, щоб звузити ваші результати до того, що вам потрібно.

// The sections we want to log and the minimum level
var LOG_LEVEL = 4;
var LOG_SECTIONS = ["section1","section2","section3"];

function logit(msg, section, level) {
  if (LOG_SECTIONS.indexOf(section) > -1 && LOG_LEVEL >= level) {
    console.log(section + ":" + msg);
  }
}

logit("message 1", "section1", 4); // will log
logit("message 2", "section2", 4); // will log
logit("message 3", "section3", 2); // wont log, below log level
logit("message 4", "section4", 4); // wont log, not in a log section

6

Просто використовуйте \ r, щоб закінчити рядок:

process.stdout.write('text\r');

Ось простий приклад (настінні годинники):

setInterval(() => process.stdout.write(`clock: ${new Date()}\r`), 1000);

Це працює, але якщо рядок "змінений" коротший за попередній, він зберігатиме деякі старі символи в терміналі.
Matthijn

5

якщо ви бачите виключення stdout, як TypeError: process.stdout.clearLine is not a functionу вікні консолі налагодження коду Visual Studio (або Webstorm), запустіть програму як зовнішню програму терміналу замість внутрішньої консолі. Причиною є те, що вікно консолі налагодження не є TTY ( process.stdout.isTTYневірно). Тому оновіть конфігурацію запуску за launch.jsonдопомогою "console": "externalTerminal"опції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.