클라이언트 측 JavaScript 프로그래밍에 익숙한 경우 Settimeout 및 SetInterval 함수를 사용하여 기능을 실행하기 전에 일정 시간 동안 지연 될 수 있습니다. 예를 들어, 웹 페이지에 1 초 후에로드 된 다음 코드는 페이지 문서 다음에 "Hello there"가 추가됩니다.
코드 사본은 다음과 같습니다.
var onesecond = 1000 * 1; // 1 초 = 1000 x 1ms
settimeout (function () {
document.write ( '<p> 안녕하세요. </p>');
}, onesecond);
SetInterval은 지정된 시간 간격에서 반복적 인 함수 실행을 허용합니다. 다음 코드가 웹 페이지에 주입되면 다음 문장 "Hello where"가 초마다 페이지 문서에 추가됩니다.
코드 사본은 다음과 같습니다.
var onesecond = 1000 * 1; // 1 초 = 1000 x 1ms
setInterval (function () {
document.write ( '<p> 안녕하세요. </p>');
}, onesecond);
웹은 오랫동안 간단한 정적 페이지가 아닌 응용 프로그램을 구축하기위한 플랫폼이되었으므로 이러한 종류의 유사한 수요는 점점 더 떠오르고 있습니다. 이러한 작업 계획 기능은 개발자가 양식의 정기적 인 검증, 원격 데이터 동기화 지연 또는 응답 지연이 필요한 UI 상호 작용을 구현할 수 있도록 도와줍니다. 노드는 또한 이러한 방법을 전체적으로 구현합니다. 서버 측면에서 캐시 만료, 연결 풀 청소, 세션 만료, 폴링 등과 같은 많은 작업의 실행을 반복하거나 지연시킬 수 있습니다.
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 ( "시간이 완성되었습니다!");
}, 타임 아웃 타임);
클리어 타임 아웃 (시간 초과);
이 예에서는 타이머가 트리거되지 않으며 "Time Out!"이라는 단어를 출력하지 않습니다. 다음 예와 같이 향후 언제든지 실행 계획을 취소 할 수도 있습니다.
코드 사본은 다음과 같습니다.
var timeout = settimeout (function a () {
Console.log ( "시간이 완성되었습니다!");
}, 2000);
settimeout (function b () {
클리어 타임 아웃 (시간 초과);
}, 1000);
코드는 지연된 실행 된 두 가지 함수 A와 B를 지정합니다. 함수 A는 2 초 후에 실행될 계획이며 B가 1 초 후에 실행될 계획입니다. 기능 B가 먼저 실행되고 A의 실행 계획을 취소하므로 A는 실행되지 않습니다.
함수의 반복 실행 계획을 개발하고 취소하십시오.
SetInterval은 settimeout과 유사하지만 지정된 시간 간격으로 기능을 반복적으로 실행합니다. 이를 사용하여 정기적으로 프로그램을 트리거하여 청소, 수집, 로깅, 데이터 수집, 폴링 등과 같이 반복 해야하는 다른 작업을 완료 할 수 있습니다.
다음 코드는 초마다 콘솔에 "진드기"를 출력합니다.
코드 사본은 다음과 같습니다.
var 기간 = 1000; // 1 초
setInterval (function () {
Console.log ( "진드기");
}, 기간);
영원히 실행되기를 원하지 않으면 ClearinterVal ()을 사용하여 타이머를 취소 할 수 있습니다.
SetInterval은 실행 계획 핸들을 반환하며, 이는 실행 계획을 취소하기 위해 ClearinterVal의 매개 변수로 사용할 수 있습니다.
코드 사본은 다음과 같습니다.
var interval = setInterVal (function () {
Console.log ( "진드기");
}, 1000);
//…
ClearInterval (간격);
Process.NextTick을 사용하여 기능 실행을 다음 라운드에서 이벤트 루프로 지연시킵니다.
때때로 클라이언트 JavaScript 프로그래머는 Settimeout (콜백, 0)을 사용하여 짧은 시간 동안 작업을 지연시킵니다. 두 번째 매개 변수는 0 밀리 초입니다. 모든 보류 이벤트가 처리 된 직후에 JavaScript 에이 콜백 기능을 실행하도록 지시합니다. 때때로이 기술은 즉시 수행 할 필요가없는 작업 실행을 지연시키는 데 사용됩니다. 예를 들어, 사용자 이벤트가 처리 된 후 애니메이션 재생을 시작하거나 다른 계산을 수행해야합니다.
노드에서 "이벤트 루프"의 문자 적 의미와 마찬가지로 이벤트 루프는 이벤트 대기열을 처리하는 루프에서 실행되며 이벤트 루프 작업의 각 라운드를 진드기라고합니다.
이벤트 루프가 다음 라운드 (다음 진드기) 실행을 시작할 때마다 한 번 콜백 함수를 호출 할 수 있습니다.이 실행은 정확히 프로세스 원칙입니다 .nextTick 및 settimeout은 이벤트 루프를 사용하는 대신 JavaScript 런타임 내부의 실행 큐를 사용합니다.
settimeout (콜백, 0) 대신 process.nexttick (콜백)을 사용하면 큐가 처리 된 직후 콜백 함수가 실행됩니다. JavaScript 타임 아웃 큐 (CPU 시간으로 측정)보다 훨씬 빠릅니다.
다음 이벤트 루프까지 기능을 지연시키고 다음과 같이 실행할 수 있습니다.
코드 사본은 다음과 같습니다.
process.nexttick (function () {
my_expensive_computation_function ();
});
참고 : 프로세스 객체는 노드의 몇 안되는 전역 객체 중 하나입니다.
이벤트 루프 차단
노드 및 JavaScript의 런타임은 단일 스레드 이벤트 루프를 사용합니다. 각 루프, 런타임은 콜백 함수를 사용하여 큐의 다음 이벤트를 처리합니다. 이벤트가 실행되면 이벤트 루프는 실행 결과를 얻고 다음 이벤트를 처리하여 이벤트 대기열이 비어있을 때까지 반복합니다. 콜백 중 하나를 실행하는 데 시간이 오래 걸리면 이벤트 루프는 해당 시간 동안 다른 보류 이벤트를 처리 할 수 없으므로 응용 프로그램이나 서비스를 매우 느리게 만들 수 있습니다.
이벤트를 처리 할 때 메모리에 민감하거나 프로세서에 민감한 기능을 사용하는 경우 이벤트 루프가 느려지고 많은 수의 이벤트가 축적되어 제 시간에 처리 될 수 없거나 큐를 차단할 수 없습니다.
이벤트 루프 차단의 다음 예를 참조하십시오.
코드 사본은 다음과 같습니다.
process.nexttick (function nexttick1 () {
var a = 0;
while (true) {
A ++;
}
});
process.nexttick (function nexttick2 () {
Console.log ( "다음 진드기");
});
settimeout (function timeout () {
Console.log ( "타임 아웃");
}, 1000);
이 예에서 NextTick2 및 TimeOut 함수는 시간이 얼마나 오래 걸리더라도 실행할 기회가 없습니다. 이벤트 루프는 NextTick 함수에서 무한 루프에 의해 차단되며 시간 초과 기능이 1 초 후에 실행 되더라도 실행되지 않습니다.
Settimeout을 사용하면 콜백 함수가 실행 계획 대기열에 추가 되며이 경우 큐에 추가되지 않습니다. 이것은 극단적 인 예이지만 프로세서에 민감한 작업을 실행하면 이벤트 루프를 차단하거나 느리게 할 수 있음을 알 수 있습니다.
이벤트 루프를 종료하십시오
process.nexttick을 사용하면 실행 전에 이벤트 루프 (TICK)의 다음 라운드에 비정상적인 작업을 연기 할 수있어 이벤트 루프를 제거하여 다른 보류 이벤트를 계속 실행할 수 있습니다.
다음 예를 참조하십시오. 임시 파일을 삭제하려고하지만 데이터 이벤트의 콜백 함수 가이 IO 작업을 기다리기를 원하지 않으면 다음과 같이 지연 될 수 있습니다.
코드 사본은 다음과 같습니다.
stream.on ( "data", function (data) {
stream.end ( "내 응답");
process.nexttick (function () {
fs.unlink ( "/path/to/file");
});
});
SetInterval 대신 Settimeout을 사용하여 기능 실행의 연속성을 보장합니다.
my_async_function이라는 함수를 설계 할 계획이라고 가정 해 봅시다.이 기능은 일부 I/O 작업 (예 : 로그 파일을 구문 분석하고 주기적으로 실행하도록 할 수 있습니다. 다음과 같은 SetInterval로 구현할 수 있습니다.
코드 사본은 다음과 같습니다.
var 간격 = 1000;
setInterval (function () {
my_async_function (function () {
console.log ( 'my_async_function 완료!');
});
}, interval); // 번역기 노트 : 이전 ", Interval"을 추가했습니다.
이러한 기능이 동시에 실행되지 않도록해야하지만 SetInterval을 사용하면이를 보장 할 수 없습니다. my_async_function 함수가 간격 변수보다 1 밀리 초 더 길어지면 순서대로 일련의 순서 대신 동시에 실행됩니다.
번역가 주 : (아래의 대담한 부분은 원본 책의 내용이 아니라 번역기에 의해 추가됩니다)
콘텐츠 의이 부분에 대한 이해를 용이하게하려면 저자의 코드를 수정하여 실제로 실행할 수 있도록 할 수 있습니다.
코드 사본은 다음과 같습니다.
var 간격 = 1000;
setInterval (function () {
(함수 my_async_function () {
settimeout (function () {
Console.log ( "1");
}, 5000);
}) ();
},간격);
이 코드를 실행하면 5 초 동안 기다린 후 "Hello"가 1 초마다 출력됩니다. 현재 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 ( '비동기가 완료되었습니다!');
일정();
});
}, 간격);
} ()); // 줄 10
이전 코드에서는 스케줄 (3 행)이라는 함수가 선언되며 선언 후 즉시 호출됩니다 (10 행). 스케줄 함수는 1 초 후에 DO_IT 함수를 실행합니다 (간격으로 지정). 1 초 후, 5 행의 my_async_function 함수가 호출됩니다. 실행되면 자체 익명 콜백 함수 (6 행)를 호출합니다. 이 익명의 콜백 함수는 do_it의 실행 계획을 다시 재설정하고 1 초 후에 다시 실행되도록 코드가 일련의 지속적으로 실행되도록합니다.
요약
settimeout () 함수를 사용하여 함수의 실행 계획을 사전 설정하고 clareTimeout () 함수로 취소 할 수 있습니다. SetInterVal ()을 사용하여 특정 함수를 주기적으로 반복적으로 실행할 수도 있습니다. 따라서 ClearinterVal ()을 사용 하여이 반복 실행 계획을 취소 할 수 있습니다.
프로세서에 민감한 작업을 사용하여 이벤트 루프가 차단되면 원래 실행될 기능이 지연되고 실행되지 않습니다. 따라서 이벤트 루프 내에서 CPU에 민감한 작업을 사용하지 마십시오. 또한 Process.nextTick ()을 사용하여 다음 이벤트 루프의 다음 라운드까지 기능 실행을 지연시킬 수 있습니다.
I/O 및 SetInterval ()를 함께 사용하면 언제든지 보류중인 호출이 하나만 있다고 보장 할 수는 없지만 재귀 함수 및 settimeout () 함수를 사용 하여이 까다로운 문제를 피할 수 있습니다.