Node.js console.log - Có thể cập nhật một dòng thay vì tạo một dòng mới không?


83

node.jsỨng dụng của tôi có rất nhiều nhật ký bảng điều khiển, điều này rất quan trọng đối với tôi (đó là một ứng dụng khá lớn nên chạy trong một thời gian dài và tôi cần biết rằng mọi thứ vẫn đang tiếp tục) nhưng tôi đang kết thúc với hàng nghìn dòng nhật ký giao diện điều khiển.

Bằng cách nào đó có thể thực hiện thao tác console.updatexóa / thay thế một dòng bảng điều khiển thay vì tạo một dòng mới?


1
Tại sao không ghi vào một tệp nhật ký mà bạn có thể theo dõi hoặc tìm kiếm?
Nelson

1
Tôi có thể làm điều đó đủ dễ dàng trong PowerShell, nhưng điều quan trọng hơn là tôi có khoảng 5.000 dòng bảng điều khiển được viết có thể dễ dàng chiếm 10 dòng (hầu hết đó chỉ là các cuộc gọi cho tôi biết rằng mọi thứ đang tiến triển, điều quan trọng là ứng dụng chạy trong khoảng 20 phút và tôi cần phản hồi về việc mọi thứ có bị hỏng / vẫn chạy hay không).
JVG

Điều này có trả lời câu hỏi của bạn không? Cách xóa các ký tự được in trong bảng điều khiển
Wex

Câu trả lời:


127

Hãy thử chơi với các phương thức process.stdout trên bảng điều khiển:

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

10
TypeError: process.stdout.clearLine không phải là một hàm. Không thể chạy trong webstorm nếu bất kỳ ai khác gặp phải điều này.
Trevor

@TrevorD cách tiếp cận của tôi để này là để thêm một webstorm=truetrong các thông số ứng dụng trong cấu hình nút webstorm và kiểm tra process.argv.find(x => x.startsWith('webstorm=true')bằng câu trả lời này
Luiz Eduardo

1
@Luiz Eduardo Sẽ không đơn giản hơn nếu chỉ gói gọn if (process.stdout.clearLine) { process.stdout.clearLine() }?
Trevor

Nắm bắt tốt! Vì lý do nào đó, tôi thậm chí còn không nghĩ đến điều đó. Vì tôi đang xây dựng một công cụ đơn giản nhỏ để chạy trong bảng điều khiển, mặc dù tôi chưa cung cấp kỹ lưỡng, nhưng tôi chắc chắn sẽ thay đổi nó, cảm ơn!
Luiz Eduardo

Tôi sẽ làm điều này: node -e "for(let i=1;i<=1000;i++){process.stdout.write('Hello, World'); if(i<10)process.stdout.clearLine(); process.stdout.cursorTo(0);}"hoặcnode -e "for(let i=1;i<=1000;i++){process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write('hello, world')}"
Cerberus

55

Theo câu trả lời của @ michelek, bạn có thể sử dụng một hàm tương tự như sau:

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

1
Khi sử dụng cái này với vòng lặp for thì bị chập chờn, có cách nào khắc phục lỗi này không?
Ank i zle

1
để sửa chữa nhấp nháy, thoát khỏiprocess.stdout.clearLine()
decoder7283

Tôi nhận ra rằng việc thêm điều này vào một vòng lặp lớn sẽ làm tăng thời gian tính toán lên đáng kể. Ví dụ: tôi đang chạy 100mil lần thử ngẫu nhiên và gán cho các biến. Sẽ mất 3 giây. với chức năng này. phải mất như một phút
Mj Jameel

đừng bận tâm đến nhận xét trên của tôi. Tôi đoán rằng tất cả các bản ghi bảng điều khiển có giá rất cao. và Kể từ khi tôi đã cố gắng để in một tiến bộ bởi tỷ lệ phần trăm tôi đã phải viết một chức năng mà chỉ in trên khoảng nhất định như 1% 2% vv
Mj Jameel

21

Chắc chắn, bạn có thể thực hiện việc này bằng cách sử dụng mô-đun mà tôi đã giúp tạo: fknsrs / jetty

Cài đặt qua

npm install jetty

Đây là một ví dụ sử dụng

// 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");

Cầu tàu không phải là siêu hữu ích khi tự sử dụng. Sẽ hiệu quả hơn nhiều khi bạn xây dựng một số trừu tượng trên đó để làm cho các cuộc gọi cầu cảng của bạn ít dài dòng hơn.


3
Tôi đã phản đối điều này vì giấy phép hạn chế trên gói này.
mmmeff

17
Đó là một licsense 3 điều khoản BSD tiêu chuẩn . Lý do khá tệ cho một cuộc bỏ phiếu, imo.
Cảm ơn bạn

6
@mmmeff, nếu bạn nghĩ giấy phép BSD 3 điều khoản là hạn chế, tôi sợ bạn sẽ chết khi nghe về giấy phép GPL và AGPL.
Michael Pfaff

15

Để viết một phần dòng.

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

Nếu khối lượng đầu ra là vấn đề thực sự thì có lẽ bạn sẽ phải suy nghĩ lại về việc ghi nhật ký của mình. Bạn có thể sử dụng một hệ thống ghi nhật ký cho phép ghi nhật ký thời gian chạy có chọn lọc để thu hẹp đầu ra của bạn cho những gì bạn cần.

// 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

Chỉ cần sử dụng \ r để kết thúc dòng của bạn:

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

Đây là một ví dụ đơn giản (đồng hồ treo tường):

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

Điều này hoạt động, nhưng nếu dòng 'đã thay đổi' ngắn hơn dòng trước đó, nó sẽ giữ một số ký tự cũ trong thiết bị đầu cuối.
Matthijn

5

nếu bạn thấy các ngoại lệ stdout như TypeError: process.stdout.clearLine is not a functiontrong cửa sổ Debug Console của Visual Studio Code (hoặc Webstorm), hãy chạy ứng dụng dưới dạng ứng dụng đầu cuối bên ngoài thay vì bảng điều khiển nội bộ. Nguyên nhân là do cửa sổ Debug Console không phải là TTY ( process.stdout.isTTYlà false). Do đó, hãy cập nhật cấu hình khởi chạy của bạn launch.jsonvới "console": "externalTerminal"tùy chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.