>  기사  >  웹 프론트엔드  >  Node.js_node.js에서 타이머를 사용하여 정기적으로 함수를 실행하는 방법에 대한 자세한 설명

Node.js_node.js에서 타이머를 사용하여 정기적으로 함수를 실행하는 방법에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 16:39:341322검색

클라이언트 측 JavaScript 프로그래밍에 익숙하다면 일정 시간 동안 함수 실행을 지연시킬 수 있는 setTimeout 및 setInterval 함수를 사용해 본 적이 있을 것입니다. 예를 들어, 다음 코드는 웹페이지에 로드되면 1초 후에 페이지 문서에 "Hello there"를 추가합니다.

코드 복사 코드는 다음과 같습니다.

var oneSecond = 1000 * 1; // 1초 = 1000 x 1ms

setTimeout(함수() {

document.write('

안녕하세요.

');

}, 1초);

그리고 setInterval을 사용하면 함수가 지정된 간격으로 반복적으로 실행될 수 있습니다. 다음 코드가 웹 페이지에 삽입되면 매초마다 페이지 문서에 "Hello there"가 추가됩니다.

코드 복사 코드는 다음과 같습니다.

                var oneSecond = 1000 * 1 // 1초 = 1000 x 1ms

setInterval(함수() {

document.write('

안녕하세요.

');

            }, oneSecond);

웹은 오랫동안 단순한 정적인 페이지가 아닌 애플리케이션 구축을 위한 플랫폼으로 자리잡았기 때문에 이와 유사한 수요가 점차 늘어나고 있습니다. 이러한 작업 예약 기능은 개발자가 주기적인 양식 유효성 검사, 지연된 원격 데이터 동기화 또는 지연된 응답이 필요한 UI 상호 작용을 구현하는 데 도움이 됩니다. Node는 또한 이러한 메소드를 완벽하게 구현합니다. 서버 측에서는 이를 사용하여 캐시 만료, 연결 풀 정리, 세션 만료, 폴링 등과 같은 많은 작업을 반복하거나 지연할 수 있습니다.

setTimeout 지연 함수를 사용하여 실행

setTimeout은 다음과 같이 지정된 함수를 나중에 한 번 실행하기 위한 실행 계획을 수립할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

                      var timeout_ms = 2000 // 2초

var timeout = setTimeout(function() {

console.log("시간 초과!");

                }, timeout_ms);

클라이언트 측 JavaScript와 정확히 동일하게 setTimeout은 두 개의 매개변수를 허용합니다. 첫 번째 매개변수는 지연되어야 하는 함수이고 두 번째 매개변수는 지연 시간(밀리초)입니다.

setTimeout은 내부 객체인 타임아웃 핸들을 반환합니다. 이를 매개변수로 사용하여 클리어타임아웃을 호출하여 타이머를 취소할 수 있습니다.

clearTimeout을 사용하여 실행 계획 취소

타임아웃 핸들을 얻은 후에는 다음과 같이 clearTimeout을 사용하여 함수 실행 계획을 취소할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

                    var timeoutTime = 1000 // 1초

var timeout = setTimeout(function() {

console.log("시간 초과!");

               }, timeoutTime);

clearTimeout(timeout);

이 예에서는 타이머가 실행되지 않으며 "time out!"이라는 단어도 출력되지 않습니다. 다음 예와 같이 향후 언제든지 실행 계획을 취소할 수도 있습니다.

코드 복사 코드는 다음과 같습니다.

var timeout = setTimeout(function A() {

console.log("시간 초과!");

                     }, 2000);

                                     setTimeout(함수 B() {

~ ~        
                    }, 1000);

코드에는 두 개의 지연 실행 함수 A와 B가 지정되어 있습니다. 함수 A는 2초 후에 실행되도록 예약되어 있고, B는 함수 B가 먼저 실행되고 A의 실행 계획을 취소하기 때문에 1초 후에 실행되도록 예약되어 있습니다. 그래서 A는 결코 달리지 않을 것입니다.

기능에 대한 반복 실행 계획 수립 및 취소

setInterval은 setTimeout과 유사하지만 지정된 간격으로 함수를 반복적으로 실행합니다. 이를 사용하면 반복적으로 수행해야 하는 정리, 수집, 로깅, 데이터 수집, 폴링 등과 같은 작업을 완료하기 위해 프로그램을 주기적으로 트리거할 수 있습니다.

다음 코드는 매초마다 콘솔에 "틱"을 출력합니다.


코드 복사 코드는 다음과 같습니다.
                var 기간 = 1000 // 1초
setInterval(함수() {

console.log("틱");

             }, 마침표);


영구 실행을 원하지 않는 경우에는clearInterval()을 사용하여 타이머를 취소할 수 있습니다.

setInterval은 실행 계획을 취소하기 위해 clearInterval의 매개변수로 사용할 수 있는 실행 계획 핸들을 반환합니다.

코드 복사 코드는 다음과 같습니다.
                var 간격 = setInterval(function() {
console.log("틱");

             }, 1000);

                                              // …

clearInterval(간격);


process.nextTick을 사용하여 이벤트 루프의 다음 라운드까지 함수 실행을 지연합니다.

클라이언트 측 JavaScript 프로그래머는 짧은 시간 동안 작업을 지연하기 위해 setTimeout(callback,0)을 사용합니다. 두 번째 매개변수는 0밀리초이며, 이는 대기 중인 모든 이벤트가 처리된 후 즉시 대기하도록 JavaScript 런타임에 지시합니다. 이 콜백 함수를 실행하십시오. 때때로 이 기술은 즉시 수행할 필요가 없는 작업의 실행을 지연시키는 데 사용됩니다. 예를 들어 사용자 이벤트가 처리된 후 애니메이션 재생을 시작하거나 다른 계산을 수행해야 하는 경우가 있습니다.

Node에서 "이벤트 루프"의 문자 그대로의 의미와 마찬가지로 이벤트 루프는 이벤트 큐를 처리하는 루프에서 실행됩니다. 이벤트 루프 작업 프로세스의 각 라운드를 틱이라고 합니다.

이벤트 루프가 다음 라운드(다음 틱) 실행을 시작할 때마다 한 번씩 콜백 함수를 호출할 수 있습니다. 이것이 바로 process.nextTick의 원칙이며, setTimeout 및 setTimeout은 JavaScript 런타임 내부의 실행 대기열을 사용합니다. 이벤트 루프를 사용하지 않습니다.

setTimeout(callback, 0) 대신 process.nextTick(콜백)을 사용하면 대기열의 이벤트가 처리된 후 콜백 함수가 즉시 실행됩니다. 이는 JavaScript의 타임아웃 대기열(측정할 CPU 시간)보다 훨씬 빠릅니다. ).

다음과 같이 이벤트 루프의 다음 라운드까지 함수를 지연할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

process.nextTick(함수() {

my_expensive_computation_function();

             });

참고: 프로세스 개체는 Node.js의 몇 안되는 전역 개체 중 하나입니다.

이벤트 루프 차단

Node와 JavaScript의 런타임은 단일 스레드 이벤트 루프를 사용합니다. 루프가 실행될 때마다 런타임은 관련 콜백 함수를 호출하여 대기열의 다음 이벤트를 처리합니다. 이벤트가 실행되면 이벤트 루프는 실행 결과를 얻고 다음 이벤트를 처리하며 이벤트 큐가 빌 때까지 계속됩니다. 콜백 함수 중 하나를 실행하는 데 오랜 시간이 걸리면 이벤트 루프는 해당 시간 동안 보류 중인 다른 이벤트를 처리할 수 없으므로 애플리케이션이나 서비스가 매우 느려질 수 있습니다.

이벤트를 처리할 때 메모리에 민감한 함수나 프로세서에 민감한 함수를 사용하면 이벤트 루프가 느려지고 많은 수의 이벤트가 누적되어 시간 내에 처리할 수 없거나 대기열을 차단할 수도 있습니다.

이벤트 루프를 차단하는 다음 예를 살펴보세요.

코드 복사 코드는 다음과 같습니다.

process.nextTick(함수 nextTick1() {

var a = 0;

동안(true) {

;

                                                                                                              }

             });

process.nextTick(function nextTick2() {

console.log("다음 틱");

             });

setTimeout(함수 시간 초과() {

console.log("timeout");

             }, 1000);


이 예에서는 nextTick 함수의 무한 루프에 의해 이벤트 루프가 차단되기 때문에 nextTick2 및 timeout 함수는 아무리 기다려도 실행될 기회가 없습니다. 1초가 지나면 실행되지 않습니다.

setTimeout을 사용하면 콜백 함수가 실행 계획 대기열에 추가되지만 이 예에서는 대기열에 추가되지도 않습니다. 이는 극단적인 예이지만 프로세서 집약적인 작업을 실행하면 이벤트 루프가 차단되거나 느려질 수 있음을 알 수 있습니다.

이벤트 루프 종료

process.nextTick을 사용하면 중요하지 않은 작업을 이벤트 루프의 다음 라운드(틱)로 연기할 수 있습니다. 그러면 이벤트 루프가 해제되어 보류 중인 다른 이벤트를 계속 실행할 수 있습니다.

아래 예를 보세요. 임시 파일을 삭제할 계획이지만 데이터 이벤트의 콜백 함수가 이 IO 작업을 기다리지 않도록 하려면 다음과 같이 지연할 수 있습니다.


코드 복사 코드는 다음과 같습니다.
                   stream.on("data", function(data) {
stream.end("내 응답");

process.nextTick(function() {

fs.unlink("/path/to/file");

                                                                                      

             });


함수 실행의 연속성을 보장하려면 setInterval 대신 setTimeout을 사용하세요

특정 I/O 작업(예: 로그 파일 구문 분석)을 수행할 수 있고 주기적으로 실행되도록 하는 my_async_function이라는 함수를 설계할 계획이라고 가정해 보겠습니다. setInterval을 사용하여 다음과 같이 구현할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

              var 간격 = 1000;

setInterval(함수() {

my_async_function(function() {

console.log('my_async_function이 완료되었습니다!');

                                                                                      

                    },interval);//번역자 주: 이전의 ",interval"은 제가 추가한 것인데, 오타로 인해 작성자가 생략했을 수도 있습니다


이러한 함수가 동시에 실행되지 않도록 보장할 수 있어야 하지만, setinterval을 사용하면 이를 보장할 수 없습니다. my_async_function 함수가 간격 변수보다 실행하는 데 1밀리초 더 오래 걸리면 해당 함수가 실행됩니다. 순서대로 실행되는 것이 아니라 동시에 실행됩니다.

번역자 주: (아래 굵은 글씨 부분은 번역자가 추가한 것으로 원서 내용이 아닙니다.)

이 부분의 콘텐츠에 대한 이해를 돕기 위해 작성자의 코드를 수정하여 실제로 실행할 수 있도록 할 수 있습니다.

코드 복사 코드는 다음과 같습니다.
                var 간격 = 1000;
setInterval(함수(){

(함수 my_async_function(){

setTimeout(함수(){

console.log("1");

                                                                                                                                             },5000);

                                                                                                                                                     

             },간격);


이 코드를 실행해 보면 5초를 기다린 후 1초마다 "hello"가 출력되는 것을 확인할 수 있습니다. 현재 my_async_function이 실행된 후(5초 소요) 다음 my_async_function을 실행하기 전에 1초 동안 기다려야 합니다. 각 출력 사이에는 6초의 간격이 있어야 합니다. 이 결과는 my_async_function이 직렬로 실행되지 않고 여러 기능이 동시에 실행되기 때문에 발생합니다.

따라서 하나의 my_async_function 실행 종료와 다음 my_async_function 실행 시작 사이의 간격이 간격 변수에 지정된 시간과 정확히 일치하도록 강제하는 방법이 필요합니다. 이렇게 할 수 있습니다:


코드 복사 코드는 다음과 같습니다.

                  var 간격 = 1000 // 1초

(함수 스케줄() { //3번째 줄

setTimeout(function do_it() {

my_async_function(function() { //5번째 줄

console.log('비동기화 완료!');

일정();

                                                                                                                                                                       

                       }, 간격);

                    }());


이전 코드에서는 Schedule이라는 함수가 선언되었고(3행) 선언 직후에 호출되었습니다(10행). Schedule 함수는 1초(간격으로 지정됨) 후에 do_it 함수를 실행합니다. 1초 후, 5번째 줄의 my_async_function 함수가 호출됩니다. 실행이 완료되면 자체 익명 콜백 함수(6번째 줄)가 호출되고, 이 익명 콜백 함수는 do_it의 실행 계획을 다시 설정하고 다시 실행하게 됩니다. 1초 후에 코드가 루프에서 연속적으로 연속적으로 실행되기 시작합니다.

요약

setTimeout() 함수를 사용하면 함수의 실행 계획을 미리 설정할 수 있고, 취소하려면clearTimeout() 함수를 사용할 수 있습니다. 또한 setInterval()을 사용하여 함수를 주기적으로 반복적으로 실행할 수도 있습니다. 그에 따라 ClearInterval()을 사용하여 이 반복 실행 계획을 취소할 수도 있습니다.

프로세서에 민감한 작업을 사용하여 이벤트 루프가 차단되면 원래 실행되도록 예약된 기능이 지연되거나 전혀 실행되지 않습니다. 따라서 이벤트 루프 내에서 CPU에 민감한 작업을 사용하지 마십시오. 또한 process.nextTick()을 사용하여 이벤트 루프의 다음 반복까지 함수 실행을 지연할 수 있습니다.

setInterval()과 함께 I/O를 사용하면 특정 시점에 보류 중인 호출이 하나만 있다고 보장할 수 없습니다. 그러나 재귀 함수와 setTimeout() 함수를 사용하면 이 까다로운 문제를 피할 수 있습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.