简体   繁体   中英

How to write to process.stdout synchroniously?

I am working on cpu heavy single threaded console utility. I am doing cpu heavy work in a single synchronious call (ie no callbacks and crap like that), however, apparently, node, for some crazy reason is doing output to terminal asynchroniously. Is there any way to deal with that issue? I am trying to display a progress bar, however, it is completely useless, because it displays it AFTER the cpu work has been done and node just does nothing but print afterwards (pointless at that point and also delays the exit).

Here is my code for progress bar I am using:

function ProgressBar(total, displayLen, prompt) { /**class*/
    this.prompt = prompt;
    this.total = total;
    this.displayLen = displayLen;
    this.perctf = 100.0 / total;
    this.displayf = 100.0 / displayLen;
    this.percprog = 0;
    this.displayprog = 0;

    this.laststr = "";
    this.dots = "";
    this.cpgrinc = 0;
    this.lastdisplayc = 0;
}

ProgressBar.prototype.update = function() {
    this.percprog += this.perctf;
    this.displayprog += this.perctf;
    if (this.displayprog > this.displayf) {
        this.dots += ".";
        this.displayprog = 0;
    }
    this.cpgrinc = (this.cpgrinc + 1) % 4;

    this.clear();
    this.laststr = this.prompt + " [" + this.dots;
    this.write(this.laststr + " " +
        this.percprog.toFixed() + "%] " + this.indicator());
};

ProgressBar.prototype.clear = function() {
    var str = "";
    for (var i = 0; i < this.lastdisplayc; i++) {
        str += "\b";
    }
    process.stdout.write(str);
};

ProgressBar.prototype.write = function(data) {
    process.stdout.write(data);
    this.lastdisplayc = data.length;
};

ProgressBar.prototype.indicator = function() {
    switch (this.cpgrinc) {
        case 0:
            return "-";
        case 1:
            return "\\";
        case 2:
            return "|";
        case 3:
            return "/";
    }
};

ProgressBar.prototype.run = function(callback) {
    var that = this;
    callback(function() {
        that.update();
    });
    this.clear();
    process.stdout.write(this.laststr + "] 100% Finished\n");
};

ProgressBar.prototype.runAsync = function(callback) {
    var that = this;
    callback(function() {
        that.update();
    }, function() {
        that.clear();
        process.stdout.write(that.laststr + "] 100% Finished\n");
    });
};

May be you can write to process.stderr if you want see it instantly.

See doc: https://nodejs.org/api/process.html#process_process_stderr

Figured out the best way:

var _fs = require('fs');
process.stdout.write = function(data) {
    try {
        _fs.writeSync(1, data);
    } catch (e) {
        process.stdout.write(data);
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM