setTimeout은 Node.JS에서 어떻게 작동합니까?


112

일단 실행되면 대기열에 있지만 대기열에는 X 밀리 초 후에 정확히 호출 될 것이라는 보장이 있습니까? 아니면 대기열에서 더 높은 다른 무거운 작업이 지연됩니까?


14
비 실시간 운영 체제는 심각한 정확성을 보장 할 수 없습니다. 시스템에있는 모든 종류의 것들이 타이머 메커니즘을 방해 할 수 있습니다.
Pointy

답변:


174

setTimeout의 의미는 웹 브라우저에서와 거의 동일합니다. timeout 인수는 보장이 아니라 실행하기 전에 대기 하는 최소 ms 수입니다. 또한 0, 숫자가 아닌 숫자 또는 음수를 전달하면 최소 ms 수만큼 대기하게됩니다. Node에서는 1ms이지만 브라우저에서는 50ms까지 가능합니다.

그 이유는 JavaScript에 의한 JavaScript의 선점이 없기 때문입니다. 이 예를 고려하십시오.

setTimeout(function () {
  console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')

여기의 흐름은 다음과 같습니다.

  1. 시간 제한을 100ms로 예약합니다.
  2. 5000ms 동안 기다립니다.
  3. 이벤트 루프로 돌아갑니다. 보류중인 타이머를 확인하고 실행합니다.

그렇지 않다면 자바 스크립트가 다른 것을 "중단"할 수 있습니다. 이와 같은 코드가 추론하기 매우 어렵지 않도록하려면 뮤텍스와 세마포 등을 설정해야합니다.

var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?

Node의 JavaScript 실행의 단일 스레드는 대부분의 다른 스타일의 동시성보다 작업하기가 훨씬 더 간단합니다. 물론, 단점은 프로그램의 잘못 동작하는 부분이 무한 루프로 모든 것을 차단할 수 있다는 것입니다.

이것은 선점의 복잡성보다 전투에 더 좋은 악마입니까? 조건에 따라서.


20
매우 정확한 console.log메시지에 대해 +1을받습니다 .
기금 모니카의 소송

문자열에서 TIME을 대문자로 사용하는 방법이 마음에 듭니다. 아주 좋은 설명 !!!
알리슨

43

비 블로킹의 개념은 루프 반복이 빠르다는 것입니다. 따라서 각 틱에 대해 반복하려면 setTimeout이 합리적인 정밀도 내에서 정확할 수있는 시간이 충분히 짧아야합니다 (약 <100ms 정도).

이론적으로는 당신 말이 맞습니다. 응용 프로그램을 작성하고 틱을 차단하면 setTimeouts가 지연됩니다. 그래서 질문에 대답하기 위해 누가 setTimeouts가 제 시간에 실행되도록 할 수 있습니까? 비 차단 코드를 작성하면 거의 모든 합리적인 정확도까지 정확도를 제어 할 수 있습니다.

자바 스크립트가 코드 실행 측면에서 "단일 스레드"인 한 (웹 작업자 등은 제외) 항상 발생합니다. 단일 스레드 특성은 대부분의 경우 크게 단순화되지만 성공하려면 비 차단 관용구가 필요합니다.

브라우저 나 노드에서이 코드를 시도해 보면 정확성이 보장되지 않는다는 것을 알 수 있습니다. 반대로 setTimeout은 매우 늦을 것입니다.

var start = Date.now();

// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);

// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}

인터프리터가 루프를 최적화하지 않는 한 (크롬에는 포함되지 않음) 수천 개를 얻을 수 있습니다. 루프를 제거하면 코에 500이 표시됩니다 ...


9

코드가 실행되도록하는 유일한 방법은 setTimeout 로직을 다른 프로세스에 배치하는 것입니다.

자식 프로세스 모듈을 사용하여 논리를 수행하고 일종의 스트림 (아마도 tcp)을 통해 해당 프로세스에 데이터를 전달하는 새 node.js 프로그램을 생성합니다.

이렇게하면 메인 프로세스에서 긴 차단 코드가 실행되고 있어도 자식 프로세스가 이미 자체적으로 시작되어 새 프로세스와 새 스레드에 setTimeout을 배치하여 예상 할 때 실행됩니다.

더 복잡한 하드웨어 수준에서 더 많은 스레드가 실행되고 프로세스가 실행되므로 컨텍스트 전환으로 인해 예상 타이밍에서 (매우 사소한) 지연이 발생합니다. 이것은 무시할 수 있어야하며 중요한 경우 수행하려는 작업, 그러한 정확성이 필요한 이유 및 대신 작업을 수행하는 데 사용할 수있는 실시간 대체 하드웨어의 종류를 심각하게 고려해야합니다.

일반적으로 하위 프로세스를 사용하고 여러 노드 애플리케이션을로드 밸런서 또는 공유 데이터 스토리지 (예 : redis)와 함께 별도의 프로세스로 실행하는 것은 코드 확장에 중요합니다.


9

setTimeout일종의 Thread 이며 주어진 시간 동안 작업을 보유하고 실행합니다.

setTimeout(function,time_in_mills);

여기서 첫 번째 인수는 함수 유형이어야합니다. 예를 들어 3 초 후에 이름을 인쇄하려면 코드는 다음과 같아야합니다.

setTimeout(function(){console.log('your name')},3000);

기억해야 할 요점은 setTimeout메소드 를 사용하여 무엇을하고 싶은지 함수 내 에서 수행한다는 것 입니다. 일부 매개 변수를 구문 분석하여 다른 메서드를 호출하려는 경우 코드는 다음과 같아야합니다.

setTimeout(function(){yourOtherMethod(parameter);},3000);

8

setTimeout(callback,t)최소 t 밀리 초 후에 콜백을 실행하는 데 사용됩니다 . 실제 지연은 OS 타이머 세분성 및 시스템로드와 같은 많은 외부 요인에 따라 달라집니다.

따라서 설정 시간이 조금 지나면 호출되지만 이전에는 호출되지 않을 가능성이 있습니다.

타이머는 24.8 일 이상 지속될 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.