자바스크립트에서 타이머에 대해 이야기할 때 우리는 반드시 setTimeout()과 setInterval() 두 가지 함수를 떠올릴 것입니다. 이 기사에서는 이벤트 루프의 관점에서 둘 사이의 작동 원리와 차이점을 분석합니다.
setTimeout()
MDN은 setTimeout을 다음과 같이 정의합니다.
지정된 지연 시간 후에 함수를 호출하거나 코드 조각을 실행합니다.
구문
setTimeout의 구문은 매우 간단합니다. 첫 번째 매개변수는 콜백 함수이고, 두 번째 매개변수는 지연 시간입니다. 이 함수는 숫자 유형의 고유 ID를 반환합니다. 이 ID는 타이머를 취소하기 위해 ClearTimeout의 매개 변수로 사용할 수 있습니다.
var timeoutID = window.setTimeout(code, Delay);
IE0+는 콜백 매개변수 전달도 지원합니다.
var timeoutID = window.setTimeout(func, Delay, [param1, param2, ...]);
setInterval( )
MDN은 setInterval을 다음과 같이 정의합니다.
주기적으로 함수를 호출하거나 코드 조각을 실행합니다.
setInterval과 setTimeout의 사용법이 동일하므로 더 이상 여기에 나열되지 않습니다.
두 번째 매개변수(delay) 설명
자바스크립트의 이벤트 루프 메커니즘으로 인해 두 번째 매개변수는 지연 밀리초 직후 콜백 함수의 실행을 나타내지 않지만, 콜백 함수가 이벤트 큐에 추가되었습니다. 실제로 이 시점에서 setTimeout과 setInterval의 처리에는 차이가 있습니다.
setTimeout: 지연 밀리초 후에는 무슨 일이 있어도 콜백 함수가 이벤트 대기열에 직접 추가됩니다.
setInterval: 밀리초 지연 후 먼저 이벤트 큐에 아직 실행되지 않은 콜백 함수(setInterval의 콜백 함수)가 있는지 확인합니다. 이벤트 큐.
따라서 코드에 시간이 많이 걸리는 작업이 있으면 타이머가 우리가 생각하는 대로 작동하지 않습니다.
예시를 통해 이해해보자
다음 코드는 원래 100ms와 200ms(즉, 100ms만 대기)에 콜백 함수를 호출할 수 있기를 바랐던 코드이다.
var 타이머Start1 = now();
setTimeout(function () {
console.log('첫 번째 setTimeout 콜백 실행 대기 시간:', now() - timeStart1);
var 타이머Start2 = now( );
setTimeout(function () {
console.log('두 번째 setTimeout 콜백 실행 대기 시간:', now() - timeStart2);
}, 100);
}, 100);
// 출력:
// 첫 번째 setTimeout 콜백 실행 대기 시간: 106
// 두 번째 setTimeout 콜백 실행 대기 시간: 107
좋아요 this 결과는 예상한 대로 보이지만, 코드에 시간이 많이 걸리는 작업을 추가하면 결과는 예상과 다릅니다.
var timeStart1 = now()
setTimeout(function () {
console.log('첫 번째 setTimeout 콜백 실행 대기 시간:', now() - timeStart1);
var 타이머Start2 = now();
setTimeout(function () {
console.log('두 번째 setTimeout 콜백 실행 대기 시간:', now() - timeStart2);
}, 100);
HeavyTask() ; // 시간이 많이 걸리는 작업
}, 100);
var loopStart = now();
heavyTask(); // 시간이 많이 걸리는 작업
console.log('heavyTask에는 시간이 걸립니다.', now() - loopStart);
function HeavyTask() {
var s = now();
while(now() - s < 1000) {
}
}
function now () {
return new Date();
}
// 출력:
// HeavyTask 시간 소비: 1015
// 첫 번째 setTimeout 콜백 실행 대기 시간: 1018
// 두 번째 setTimeout 콜백 실행 대기 시간: 1000
두 setTimeout의 대기 이벤트는 시간이 많이 걸리는 작업으로 인해 더 이상 100ms가 아닙니다. 무슨 일이 일어났는지 설명해 보겠습니다.
먼저 시간이 많이 걸리는 첫 번째 작업(heavyTask())이 실행되기 시작하고 완료하는 데 약 1000ms가 걸립니다.
시간이 많이 걸리는 작업 실행을 시작합니다. 100ms 후에 첫 번째 setTimeout 콜백 함수가 실행될 것으로 예상되므로 이벤트 큐에 추가됩니다. 그러나 이전 시간이 많이 걸리는 작업은 아직 실행되지 않았습니다. , 그래서 큐에서 기다릴 수 있고 시간이 많이 걸리는 작업이 완료될 때까지 실행을 시작하지 않으므로 결과에 표시되는 내용은 다음과 같습니다. 첫 번째 setTimeout 콜백 실행 대기 시간: 1018.
첫 번째 setTimeout 콜백이 실행되자마자 두 번째 setTimeout이 시작됩니다. 이 타이머도 100ms 지연 후 콜백 기능을 실행해야 합니다. 그러나 첫 번째 setTimeout에는 시간이 많이 걸리는 또 다른 작업이 있습니다. 해당 작업의 플롯은 첫 번째 타이머와 동일하며 실행을 시작하기 전에 1000ms를 기다립니다.
다음 사진으로 요약할 수 있습니다.
setInterval의 예를 살펴보겠습니다.
var IntervalStart = now();
setInterval(function () {
console.log(' 간격 타이머가 정의된 이후의 시간: ', now() - loopStart);
}, 100);
var loopStart = now();
heavyTask();
console .log ('heavyTask에는 시간이 걸립니다:', now() - loopStart);
function HeavyTask() {
var s = now();
while(now() - s < 1000) {
}
}
function now () {
return new Date();
}
// 출력:
// 무거운Task 시간 소모 : 1013
//정의된 타이머의 간격 시간: 1016
//정의된 타이머의 간격 시간: 1123
//정의된 타이머의 간격 시간: 1224
위 코드에서는 100ms마다 로그를 인쇄할 것으로 예상됩니다. setTimeout과 비교하여, setInterval은 이벤트 큐에 콜백 함수를 추가하려고 준비할 때 큐에 실행되지 않은 콜백이 있는지 확인합니다. 그렇다면 콜백 함수를 큐에 추가하지 않습니다. 그렇지 않으면 여러 콜백이 동시에 실행됩니다.
다음 다이어그램으로 요약할 수 있습니다.
요약
위는 JavaScript 타이머 실행 원리를 간략하게 분석한 것입니다. 이것이 우리가 자바스크립트를 더 깊이 이해하는 데 도움이 되기를 바랍니다. 기사에 부적절한 설명이 있는 경우 댓글로 지적해주세요.
자바스크립트 타이머의 작동 원리와 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!