ความแตกต่างระหว่าง“ process.stdout.write” และ“ console.log” ใน node.js หรือไม่


323

อะไรคือความแตกต่างระหว่าง "process.stdout.write" และ "console.log" ใน node.js?

แก้ไข: การใช้ console.log สำหรับตัวแปรแสดงอักขระที่อ่านไม่ได้จำนวนมากในขณะที่ใช้ process.stdout.write แสดงวัตถุ

ทำไมถึงเป็นอย่างนั้น?


4
คุณสามารถยกตัวอย่างได้หรือไม่? console.log () เรียก process.stdout.write พร้อมเอาต์พุตที่จัดรูปแบบ ดู format () ใน console.js สำหรับการนำไปใช้
TK-421

คำตอบ:


324

console.log()โทรออกprocess.stdout.writeด้วยรูปแบบเอาท์พุท ดูformat()ใน console.js สำหรับการนำไปใช้

ปัจจุบัน (v0.10.ish):

Console.prototype.log = function() {
  this._stdout.write(util.format.apply(this, arguments) + '\n');
};

34
นอกจากนี้มูลค่าการกล่าวขวัญที่console.log()ดูเหมือนจะเพิ่มขึ้นบรรทัดใหม่
jchook

144

ดูที่ Node docs apparently console.log เป็นเพียง process.stdout.write ที่มีตัวแบ่งบรรทัดที่ท้าย:

console.log = function (d) {
  process.stdout.write(d + '\n');
};

แหล่งที่มา: http://nodejs.org/docs/v0.3.1/api/process.html#process.stdout


18
สำหรับผู้ที่มาในภายหลังโปรดทราบว่า v0.3.1 เป็นเวลานานแล้วและสิ่งต่าง ๆ ได้เปลี่ยนไปนับ แต่นั้นมา :)
เบรนแดน

5
... Nope เพิ่งดูที่ v0.9.9 docs และ console.log ยังคงเป็นเพียงนามแฝงของ process.stdout.write ด้วย linebreak กรุณาทำวิจัยของคุณก่อนที่จะแสดงความคิดเห็น nodejs.org/docs/v0.9.9/api/process.html#process.stdout
Mauvis Ledford

13
1) v0.9.9 มีอายุสองปี 2) เอกสารนั้นไม่ถูกต้องตาม v0.9.9 รูปแบบจะถูกแก้ไขผ่าน util
Brendan

4
ที่จริงแล้วดูเหมือนว่าเอกสารนั้นยังไม่เคยอัปเดตและยังอยู่ใกล้ ๆ ฉันจะส่งการประชาสัมพันธ์ในการแก้ไขปัญหาที่ขอบคุณสำหรับการแจ้งเตือนฉันของปัญหาที่ :)
เบรนแดน

นอกจากนี้nodejs.org/docs/latest/api/...และnodejs.org/docs/latest/api/...
Charles Wood

66

ฉันรู้ว่านี้เป็นคำถามที่เก่ามาก แต่ผมไม่เห็นใครพูดคุยเกี่ยวกับความแตกต่างที่สำคัญระหว่างprocess.stdout.writeและconsole.logและผมแค่อยากจะพูดถึงมัน

ดังที่Mauvis LefordและTK-421ชี้ให้เห็นตัวละครconsole.logจะเพิ่มline-breakตัวละครที่ท้ายบรรทัด ( \n) แต่นั่นไม่ใช่สิ่งที่มันทำ

รหัสไม่ได้เปลี่ยนตั้งแต่0.10.Xรุ่นอย่างน้อยและตอนนี้เรามี5.Xรุ่นaa

นี่คือรหัส:

Console.prototype.log = function() {
  this._stdout.write(util.format.apply(this, arguments) + '\n');
};

อย่างที่คุณเห็นมีส่วนหนึ่งที่กล่าว.apply(this, arguments)และสร้างความแตกต่างอย่างมากต่อการทำงาน มันง่ายที่จะอธิบายด้วยตัวอย่าง:

process.stdout.write มีฟังก์ชั่นพื้นฐานมาก ๆ คุณสามารถเขียนอะไรบางอย่างในนั้นแบบนี้

process.stdout.write("Hello World\n"); 

หากคุณไม่ใส่จุดพักในตอนท้ายคุณจะได้ตัวละครแปลก ๆ หลังจากสายของคุณบางอย่างเช่นนี้:

process.stdout.write("Hello World"); //Hello World% 

(ฉันคิดว่านั่นหมายถึงบางอย่างเช่น "จุดสิ้นสุดของโปรแกรม" ดังนั้นคุณจะเห็นได้เฉพาะเมื่อคุณprocess.stdout.writeใช้ที่ท้ายไฟล์และคุณไม่ได้เพิ่มจุดพัก)

ในทางกลับกันconsole.logสามารถทำได้มากกว่านี้

  1. คุณสามารถใช้มันในลักษณะเดียวกัน

    console.log("Hello World"); //You don't need the break line here because it was already formated และตัวละครแปลก ๆ ก็หายไปเช่นกัน

  2. คุณสามารถเขียนได้มากกว่าหนึ่งสตริง

    console.log("Hello", "World");

  3. คุณสามารถสร้างความสัมพันธ์

    console.log("Hello %s", "World") //Useful when "World" is inside a variable

นั่นคือมัน, ฟังก์ชั่นที่เพิ่มเข้ามาได้รับการขอบคุณจากutil.format.applyส่วนหนึ่ง (ฉันสามารถพูดคุยเกี่ยวกับสิ่งที่มันทำ แต่คุณได้รับจุดของฉันคุณสามารถอ่านเพิ่มเติมได้ที่นี่ )

ฉันหวังว่าบางคนจะพบว่าข้อมูลนี้มีประโยชน์


มันจะมีประโยชน์มากเช่นกันหากคุณอธิบายวิธีใช้stdout.writeและหลีกเลี่ยงการรับ%
Muhammad Aref

ฉันแก้ไขปัญหาของการ%ไปถึงจุดสิ้นสุดโดยเพียงโทรไปprocess.stdout.write('\n');ที่จุดสิ้นสุดของลูปของฉัน (ถ้าคุณมีตัวอย่าง)
มูฮัมหมัด Aref

2
นี่%เป็นเพียงวิธีที่เชลล์บอกว่าไม่มีบรรทัดใหม่ที่ท้ายไฟล์
เดฟนิวตัน

1
@DaveNewton จุดของคุณมีความสำคัญเพราะมันหมายความว่าหากคุณเปลี่ยนเส้นทางการส่งออกของโปรแกรมไปยังไฟล์เช่นคุณจะไม่ได้รับสิ่งนั้น%ในไฟล์
mr.mams

31

ความแตกต่างที่สำคัญอย่างหนึ่งที่ไม่ได้กล่าวถึงคือprocess.stdoutใช้สตริงเป็นอาร์กิวเมนต์เท่านั้น (สามารถเป็นสตรีมแบบ piped) ในขณะที่console.logใช้ชนิดข้อมูล Javascript ใด ๆ

เช่น:

// ok
console.log(null)
console.log(undefined)
console.log('hi')
console.log(1)
console.log([1])
console.log({one:1})
console.log(true)
console.log(Symbol('mysymbol'))

// any other data type passed as param will throw a TypeError
process.stdout.write('1')

// can also pipe a readable stream (assuming `file.txt` exists)
const fs = require('fs')
fs.createReadStream('file.txt').pipe(process.stdout)

15

อีกความแตกต่างที่สำคัญในบริบทนี้จะมีและprocess.stdout.clearLine()process.stdout.cursorTo(0)

สิ่งนี้จะมีประโยชน์หากคุณต้องการแสดงเปอร์เซ็นต์ของการดาวน์โหลดหรือการประมวลผลในบรรทัดเดียวเท่านั้น หากคุณใช้ clearLine (), cursorTo () ด้วยconsole.log()จะไม่ทำงานเพราะมันจะผนวก \ n เข้ากับข้อความ ลองตัวอย่างนี้:

var waitInterval = 500;
var totalTime = 5000;
var currentInterval = 0;

function showPercentage(percentage){
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    console.log(`Processing ${percentage}%...` ); //replace this line with process.stdout.write(`Processing ${percentage}%...`);
}

var interval = setInterval(function(){
 currentInterval += waitInterval;
 showPercentage((currentInterval/totalTime) * 100);
}, waitInterval);

setTimeout(function(){
 clearInterval(interval); 
}, totalTime);

นี่คือสิ่งที่ฉันกำลังมองหา ขอบคุณ
Patrick P.

5

ฉันเพิ่งสังเกตเห็นบางสิ่งบางอย่างในขณะที่ค้นคว้าสิ่งนี้หลังจากได้รับความช่วยเหลือเกี่ยวกับวิธีการโพสต์ https.request คิดว่าฉันแบ่งปันข้อมูลบางอย่างเพื่อช่วยให้เข้าใจ

process.stdout.writeไม่ต้องเพิ่มบรรทัดใหม่ในขณะที่console.logทำเหมือนที่คนอื่นพูดถึง แต่ก็มีสิ่งนี้ซึ่งอธิบายได้ง่ายกว่าด้วยตัวอย่าง

var req = https.request(options, (res) => {
    res.on('data', (d) => {
        process.stdout.write(d);
        console.log(d)
    });
});

process.stdout.write(d);จะพิมพ์ข้อมูลอย่างถูกต้องโดยไม่ต้องขึ้นบรรทัดใหม่ อย่างไรก็ตามconsole.log(d)จะพิมพ์บรรทัดใหม่ แต่ข้อมูลไม่แสดงอย่างถูกต้อง<Buffer 12 34 56...ยกตัวอย่างเช่น

เพื่อให้การconsole.log(d)แสดงข้อมูลถูกต้องฉันต้องทำเช่นนี้

var req = https.request(options, (res) => {
    var dataQueue = "";    
    res.on("data", function (d) {
        dataQueue += d;
    });
    res.on("end", function () {
        console.log(dataQueue);
    });
});

ดังนั้นโดยทั่วไป:

  • process.stdout.write พิมพ์ข้อมูลอย่างต่อเนื่องเมื่อมีการดึงข้อมูลและไม่เพิ่มบรรทัดใหม่

  • console.log พิมพ์ข้อมูลที่ได้รับ ณ จุดที่เรียกข้อมูลและเพิ่มบรรทัดใหม่

นั่นเป็นวิธีที่ดีที่สุดที่ฉันสามารถอธิบายได้


1

Simple Difference คือ: วิธีconsole.log ()ต่อท้ายอักขระบรรทัดใหม่โดยอัตโนมัติ หมายความว่าถ้าเราวนซ้ำและพิมพ์ผลลัพธ์ผลลัพธ์แต่ละรายการจะถูกพิมพ์ในบรรทัดใหม่

process.stdout.write ()วิธีการไม่ผนวกอักขระบรรทัดใหม่ มีประโยชน์สำหรับรูปแบบการพิมพ์


0

Console.log ใช้ process.sdout.write, process.sdout.write เป็นบัฟเฟอร์ / สตรีมที่จะส่งออกโดยตรงในคอนโซลของคุณ

ตาม puglin serverlineของฉัน: console = new Console(consoleOptions)คุณสามารถเขียนคลาส Console ใหม่ด้วยระบบreadlineของคุณเอง

คุณสามารถดูซอร์สโค้ดของ console.log:


ดูเพิ่มเติม :

  • readline.createInterfaceเพื่อสร้างพฤติกรรมที่กำหนดเองของคุณหรือใช้อินพุตคอนโซล
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.