node.js의 console.log는 비동기입니까?


95

인가 console.log/debug/warn/errorNode.js를 asynchrounous에? 내 말은 자바 스크립트 코드 실행이 화면에 인쇄 될 때까지 중단됩니까 아니면 나중에 인쇄 될까요?

또한, console.log가 노드를 충돌시킨 직후 명령문이 표시되면 아무것도 표시하지 않을 수 있는지 알고 싶습니다.

답변:


102

업데이트 : Node 0.6부터이 게시물은 stdout이 현재 동기식 이므로 더 이상 사용되지 않습니다 .

console.log실제로 무엇을하는지 봅시다 .

우선 콘솔 모듈 의 일부입니다 .

exports.log = function() {
  process.stdout.write(format.apply(this, arguments) + '\n');
};

따라서 process.stdout지금까지 비동기식이 아닌 일부 서식을 지정하고 씁니다 .

process.stdout느리게 초기화되는 시작시 정의 된 게터 이므로 설명하기 위해 몇 가지 주석을 추가했습니다.

.... code here...
process.__defineGetter__('stdout', function() {
  if (stdout) return stdout;                            // only initialize it once 

  /// many requires here ...

  if (binding.isatty(fd)) {                             // a terminal? great!
    stdout = new tty.WriteStream(fd);
  } else if (binding.isStdoutBlocking()) {              // a file?
    stdout = new fs.WriteStream(null, {fd: fd});
  } else {
    stdout = new net.Stream(fd);                        // a stream? 
                                                        // For example: node foo.js > out.txt
    stdout.readable = false;
  }

  return stdout;
});

TTY와 UNIX의 경우 여기서 끝납니다 . 이것은 소켓에서 상속됩니다. 따라서 그 노드가 기본적으로하는 일은 데이터를 소켓에 푸시하는 것입니다. 그러면 터미널이 나머지를 처리합니다.

테스트 해 봅시다!

var data = '111111111111111111111111111111111111111111111111111';
for(var i = 0, l = 12; i < l; i++) {
    data += data; // warning! gets very large, very quick
}

var start = Date.now();
console.log(data);
console.log('wrote %d bytes in %dms', data.length, Date.now() - start);

결과

....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms

real    0m0.969s
user    0m0.068s
sys  0m0.012s

터미널은 소켓 내용을 출력하는 데 약 1 초가 필요하지만 노드는 데이터를 터미널로 푸시하는 데 17 밀리 초 만 필요합니다.

스트림 케이스도 마찬가지이며 파일 케이스도 비동기 핸들을 가져옵니다 .

그래서 Node.js를 그 비 차단 약속에 충실 보유하고 있습니다.


2
업데이트 : node.js의 stdout이 이제 동기식입니다. groups.google.com/group/nodejs/browse_thread/thread/…
dhruvbird

1
나는 이것이 지금 쓸모가 없다고
tforgione

@IvoWetzel 구식이기 때문에 지금 이것을 다운 투표해야 할 것입니다.
Evan Carroll

나는이되지 않는 모든 것을 알고,하지만 당신은 즉시 "아무것도 비동기 지금까지"말하는 process.stdout.write()write()... 정의 비동기입니다
binki

26

console.warn () 및 console.error ()가 차단됩니다. 기본 시스템 호출이 성공할 때까지 반환되지 않습니다.

예, stdout에 기록 된 모든 내용이 플러시되기 전에 프로그램이 종료 될 수 있습니다. process.exit ()는 stdout에 대한 쓰기가 큐에 남아 있더라도 즉시 노드를 종료합니다. 이 동작을 방지하려면 console.warn을 사용해야합니다.


1
Windows의 노드 0.10.25에는 해당되지 않습니다. console.warn()console.error()동일한 비 차단 동작을 갖습니다 console.log(). Windows에서 문제를 해결 하는 패키지 도 있습니다 .
Lucio Paiva 2014

12

내 결론, Node.js 10. * 문서를 읽은 후 (아래 첨부). 로깅을 위해 console.log를 사용할 수 있고 console.log 는 동기식이며 낮은 수준의 c로 구현 된다는 것 입니다. console.log는 동시 적이지만 방대한 양의 데이터를 로깅하지 않는 경우에만 성능 문제가 발생하지 않습니다.

(아래의 명령 줄 예제는 console.log async 및 console.error는 sync입니다. )

Node.js 문서 에 기반

콘솔 기능은 대상이 터미널 또는 파일 인 경우 (조기 종료시 메시지 손실을 방지하기 위해) 동기식이고 파이프 인 경우 (장기간 차단을 방지하기 위해) 비동기식입니다.

즉, 다음 예제에서 stdout은 비 차단이고 stderr은 차단됩니다.

$ node script.js 2> error.log | tee info.log

일상적인 사용에서 차단 / 비 차단 이분법은 엄청난 양의 데이터를 기록하지 않는 한 걱정할 필요가 없습니다.

도움이되기를 바랍니다.


"대량의 데이터"란 무엇입니까? console.log에 대한 호출 수 또는 기록되는 총량으로 정의됩니까? 거대한 1KB / ms, 1MB / ms, 1GB / ms는 무엇입니까?
MattG

3

Console.log는 Windows에서 비동기식이지만 linux / mac에서는 동기식입니다. Windows에서 console.log를 동기식으로 만들려면 코드 시작 부분에이 줄을 아마도 index.js 파일에 작성하십시오. 이 명령문 이후의 모든 console.log는 인터프리터에 의해 동기식으로 간주됩니다.

if (process.stdout._handle) process.stdout._handle.setBlocking(true);

그런데 리눅스는 우분투가 아닙니다.
ozanmuyes

고마워, 실례지만 데비안은 내 약점이며 요즘 Linux를 사용하기 시작한 모든 사람들은 Ubuntu Linux 라고 생각하는 것 같습니다 (당신을 제외하고는 당신이 그들 중 하나가 아니라는 것을 알고 있습니다). 좋은 하루 :) 되세요
ozanmuyes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.