클라이언트 측 JavaScript 프로그래밍에 익숙하다면 일정 시간 동안 함수 실행을 지연시킬 수 있는 setTimeout 및 setInterval 함수를 사용해 본 적이 있을 것입니다. 예를 들어, 다음 코드는 웹페이지에 로드되면 1초 후에 페이지 문서에 "Hello there"를 추가합니다.
setTimeout(함수() {
document.write('
안녕하세요.
');}, 1초);
그리고 setInterval을 사용하면 함수가 지정된 간격으로 반복적으로 실행될 수 있습니다. 다음 코드가 웹 페이지에 삽입되면 매초마다 페이지 문서에 "Hello there"가 추가됩니다.
setInterval(함수() {
document.write('
안녕하세요.
'); }, oneSecond);
웹은 오랫동안 단순한 정적인 페이지가 아닌 애플리케이션 구축을 위한 플랫폼으로 자리잡았기 때문에 이와 유사한 수요가 점차 늘어나고 있습니다. 이러한 작업 예약 기능은 개발자가 주기적인 양식 유효성 검사, 지연된 원격 데이터 동기화 또는 지연된 응답이 필요한 UI 상호 작용을 구현하는 데 도움이 됩니다. Node는 또한 이러한 메소드를 완벽하게 구현합니다. 서버 측에서는 이를 사용하여 캐시 만료, 연결 풀 정리, 세션 만료, 폴링 등과 같은 많은 작업을 반복하거나 지연할 수 있습니다.
setTimeout 지연 함수를 사용하여 실행
setTimeout은 다음과 같이 지정된 함수를 나중에 한 번 실행하기 위한 실행 계획을 수립할 수 있습니다.
var timeout = setTimeout(function() {
console.log("시간 초과!");
}, timeout_ms);
클라이언트 측 JavaScript와 정확히 동일하게 setTimeout은 두 개의 매개변수를 허용합니다. 첫 번째 매개변수는 지연되어야 하는 함수이고 두 번째 매개변수는 지연 시간(밀리초)입니다.
setTimeout은 내부 객체인 타임아웃 핸들을 반환합니다. 이를 매개변수로 사용하여 클리어타임아웃을 호출하여 타이머를 취소할 수 있습니다.
clearTimeout을 사용하여 실행 계획 취소
타임아웃 핸들을 얻은 후에는 다음과 같이 clearTimeout을 사용하여 함수 실행 계획을 취소할 수 있습니다.
var timeout = setTimeout(function() {
console.log("시간 초과!");
}, timeoutTime);
clearTimeout(timeout);
이 예에서는 타이머가 실행되지 않으며 "time out!"이라는 단어도 출력되지 않습니다. 다음 예와 같이 향후 언제든지 실행 계획을 취소할 수도 있습니다.
기능에 대한 반복 실행 계획 수립 및 취소
setInterval은 setTimeout과 유사하지만 지정된 간격으로 함수를 반복적으로 실행합니다. 이를 사용하면 반복적으로 수행해야 하는 정리, 수집, 로깅, 데이터 수집, 폴링 등과 같은 작업을 완료하기 위해 프로그램을 주기적으로 트리거할 수 있습니다.다음 코드는 매초마다 콘솔에 "틱"을 출력합니다.
console.log("틱");
}, 마침표);
setInterval은 실행 계획을 취소하기 위해 clearInterval의 매개변수로 사용할 수 있는 실행 계획 핸들을 반환합니다.
}, 1000);
// …
clearInterval(간격);
process.nextTick을 사용하여 이벤트 루프의 다음 라운드까지 함수 실행을 지연합니다.
클라이언트 측 JavaScript 프로그래머는 짧은 시간 동안 작업을 지연하기 위해 setTimeout(callback,0)을 사용합니다. 두 번째 매개변수는 0밀리초이며, 이는 대기 중인 모든 이벤트가 처리된 후 즉시 대기하도록 JavaScript 런타임에 지시합니다. 이 콜백 함수를 실행하십시오. 때때로 이 기술은 즉시 수행할 필요가 없는 작업의 실행을 지연시키는 데 사용됩니다. 예를 들어 사용자 이벤트가 처리된 후 애니메이션 재생을 시작하거나 다른 계산을 수행해야 하는 경우가 있습니다.
Node에서 "이벤트 루프"의 문자 그대로의 의미와 마찬가지로 이벤트 루프는 이벤트 큐를 처리하는 루프에서 실행됩니다. 이벤트 루프 작업 프로세스의 각 라운드를 틱이라고 합니다.
이벤트 루프가 다음 라운드(다음 틱) 실행을 시작할 때마다 한 번씩 콜백 함수를 호출할 수 있습니다. 이것이 바로 process.nextTick의 원칙이며, setTimeout 및 setTimeout은 JavaScript 런타임 내부의 실행 대기열을 사용합니다. 이벤트 루프를 사용하지 않습니다.
setTimeout(callback, 0) 대신 process.nextTick(콜백)을 사용하면 대기열의 이벤트가 처리된 후 콜백 함수가 즉시 실행됩니다. 이는 JavaScript의 타임아웃 대기열(측정할 CPU 시간)보다 훨씬 빠릅니다. ).
다음과 같이 이벤트 루프의 다음 라운드까지 함수를 지연할 수 있습니다.
my_expensive_computation_function();
});
참고: 프로세스 개체는 Node.js의 몇 안되는 전역 개체 중 하나입니다.
이벤트 루프 차단
Node와 JavaScript의 런타임은 단일 스레드 이벤트 루프를 사용합니다. 루프가 실행될 때마다 런타임은 관련 콜백 함수를 호출하여 대기열의 다음 이벤트를 처리합니다. 이벤트가 실행되면 이벤트 루프는 실행 결과를 얻고 다음 이벤트를 처리하며 이벤트 큐가 빌 때까지 계속됩니다. 콜백 함수 중 하나를 실행하는 데 오랜 시간이 걸리면 이벤트 루프는 해당 시간 동안 보류 중인 다른 이벤트를 처리할 수 없으므로 애플리케이션이나 서비스가 매우 느려질 수 있습니다.
이벤트를 처리할 때 메모리에 민감한 함수나 프로세서에 민감한 함수를 사용하면 이벤트 루프가 느려지고 많은 수의 이벤트가 누적되어 시간 내에 처리할 수 없거나 대기열을 차단할 수도 있습니다.
이벤트 루프를 차단하는 다음 예를 살펴보세요.
var a = 0;
동안(true) {
;
}
});process.nextTick(function nextTick2() {
console.log("다음 틱");
});
setTimeout(함수 시간 초과() {
console.log("timeout");
}, 1000);
setTimeout을 사용하면 콜백 함수가 실행 계획 대기열에 추가되지만 이 예에서는 대기열에 추가되지도 않습니다. 이는 극단적인 예이지만 프로세서 집약적인 작업을 실행하면 이벤트 루프가 차단되거나 느려질 수 있음을 알 수 있습니다.
이벤트 루프 종료
process.nextTick을 사용하면 중요하지 않은 작업을 이벤트 루프의 다음 라운드(틱)로 연기할 수 있습니다. 그러면 이벤트 루프가 해제되어 보류 중인 다른 이벤트를 계속 실행할 수 있습니다.아래 예를 보세요. 임시 파일을 삭제할 계획이지만 데이터 이벤트의 콜백 함수가 이 IO 작업을 기다리지 않도록 하려면 다음과 같이 지연할 수 있습니다.
process.nextTick(function() {
fs.unlink("/path/to/file");
});
특정 I/O 작업(예: 로그 파일 구문 분석)을 수행할 수 있고 주기적으로 실행되도록 하는 my_async_function이라는 함수를 설계할 계획이라고 가정해 보겠습니다. setInterval을 사용하여 다음과 같이 구현할 수 있습니다.
setInterval(함수() {
my_async_function(function() {
console.log('my_async_function이 완료되었습니다!');
},interval);//번역자 주: 이전의 ",interval"은 제가 추가한 것인데, 오타로 인해 작성자가 생략했을 수도 있습니다
번역자 주: (아래 굵은 글씨 부분은 번역자가 추가한 것으로 원서 내용이 아닙니다.)
이 부분의 콘텐츠에 대한 이해를 돕기 위해 작성자의 코드를 수정하여 실제로 실행할 수 있도록 할 수 있습니다.
(함수 my_async_function(){
setTimeout(함수(){
console.log("1");
},5000);
},간격);
이 코드를 실행해 보면 5초를 기다린 후 1초마다 "hello"가 출력되는 것을 확인할 수 있습니다. 현재 my_async_function이 실행된 후(5초 소요) 다음 my_async_function을 실행하기 전에 1초 동안 기다려야 합니다. 각 출력 사이에는 6초의 간격이 있어야 합니다. 이 결과는 my_async_function이 직렬로 실행되지 않고 여러 기능이 동시에 실행되기 때문에 발생합니다.