>웹 프론트엔드 >JS 튜토리얼 >JavaScript의 타이머 원리 분석

JavaScript의 타이머 원리 분석

黄舟
黄舟원래의
2017-11-18 13:53:481617검색

우리 작업에서 많은 사람들은 javascripttimer에 대해 이야기할 때 setTimeout()과 setInterval() 두 가지 함수를 떠올릴 것입니다. 그러나 그들은 JavaScript에서 타이머의 원리가 무엇인지 모르기 때문에 이 글을 씁니다. 이벤트부터 시작하겠습니다. 이벤트 루프의 관점에서 타이머 기능의 작동 원리와 차이점을 분석해 보세요!

setTimeout()

MDN은 setTimeout를 다음과 같이 정의합니다.

지정된 지연 시간 후에 함수를 호출하거나 코드 조각을 실행합니다.

Syntax

setTimeout의 구문은 매우 간단합니다. 첫 번째 매개변수는 콜백 함수이고 두 번째 매개변수는 지연 시간입니다. 이 함수는 숫자 유형의 ID 고유 식별자를 반환합니다. 이 ID는 타이머를 취소하기 위해clearTimeout의 매개 변수로 사용할 수 있습니다.

var timeoutID = window.setTimeout(code, delay);

IE0+는 콜백 매개 변수 전달도 지원합니다.

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

setInterval()

MDN 맞습니다. setInterval의 정의는 다음과 같습니다.

주기적으로 함수(function)를 호출하거나 코드 조각을 실행합니다.

setInterval과 setTimeout의 사용법이 동일하므로 여기에 더 이상 나열되지 않습니다.

두 번째 매개변수 설명(delay)

자바스크립트의 이벤트 루프 메커니즘으로 인해 두 번째 매개변수는 지연 밀리초 후에 바로 콜백 함수를 실행한다는 의미가 아니라 이벤트 큐에 콜백 함수를 추가하려고 시도합니다. 실제로 이 시점에서 setTimeout과 setInterval의 처리에는 차이가 있습니다.

  • setTimeout: 밀리초 지연 후에는 무슨 일이 있어도 콜백 함수가 이벤트 대기열에 직접 추가됩니다.

  • setInterval: 지연 밀리초 후 먼저 이벤트 큐에 아직 실행되지 않은 콜백 함수(setInterval의 콜백 함수)가 있는지 확인합니다. 존재하는 경우 이벤트에 콜백 함수를 추가하지 마세요. 대기줄.

따라서 코드에 시간이 많이 걸리는 작업이 있으면 타이머가 우리가 생각하는 대로 작동하지 않습니다.

예를 통해 다음 코드를 이해해 보겠습니다. 원래는 100ms와 200ms에서 콜백 함수를 호출할 수 있기를 바랐습니다(즉, 100ms만 기다리면 됩니다).

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);
 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 100);
}, 100);
// 输出:
// 第一个setTimeout回调执行等待时间: 106
// 第二个setTimeout回调执行等待时间: 107

이 결과는 우리가 생각한 것과 정확히 같습니다. 시간이 많이 걸리는 작업을 코드에 추가했는데 결과가 예상했던 것과 다릅니다.

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);

 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 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가 걸립니다.
  1. 시간이 많이 걸리는 작업부터 실행을 시작합니다. 100ms 후에 첫 번째 setTimeout 콜백 함수가 실행될 것으로 예상되므로 이벤트 큐에 추가됩니다. 그러나 이전 시간이 많이 걸리는 작업은 아직 실행되지 않았습니다. 따라서 대기열에서만 대기할 수 있고 시간이 많이 걸리는 작업이 완료될 때까지 실행을 시작하지 않으므로 결과에 표시되는 내용은 다음과 같습니다. 첫 번째 setTimeout 콜백 실행 대기 시간: 1018.
  2. 첫 번째 setTimeout 콜백이 실행되자마자 두 번째 setTimeout이 시작됩니다. 이 타이머도 100ms 지연 후 콜백 기능을 실행해야 합니다. 그러나 첫 번째 setTimeout에는 시간이 많이 걸리는 또 다른 작업이 있습니다. 해당 작업의 플롯은 첫 번째 타이머와 동일하며 실행을 시작하기 전에 1000ms를 기다립니다.
  3. 은 다음 그림으로 요약할 수 있습니다.

setInterval의 예를 살펴보겠습니다.

var intervalStart = now();
setInterval(function () {
 console.log(&#39;interval距定义定时器的时间:&#39;, now() - loopStart);
}, 100);
var loopStart = now();
heavyTask();
console.log(&#39;heavyTask耗费时间:&#39;, now() - loopStart);
function heavyTask() {
 var s = now();
 while(now() - s < 1000) {
 }
}
function now () {
 return new Date();
}
// 输出:
// heavyTask耗费时间: 1013
// interval距定义定时器的时间: 1016
// interval距定义定时器的时间: 1123
// interval距定义定时器的时间: 1224

위 코드에서 우리는 100ms마다 로그를 인쇄할 것으로 예상합니다. setTimeout과 비교하여, setInterval은 이벤트 큐에 콜백 함수를 추가하려고 준비할 때 큐에 실행되지 않은 콜백이 있는지 확인합니다. 그렇다면 콜백 함수를 큐에 추가하지 않습니다. 그렇지 않으면 여러 콜백이 동시에 실행됩니다.

다음 그림으로 요약할 수 있습니다.

요약:

이상은 JavaScript 타이머의 실행 원리를 간략하게 분석한 것입니다. JavaScript의 작동 원리는 모두가 이해하고 있다고 믿습니다. 타이머. 어느 정도 이해하고 있으며 도움이 되기를 바랍니다.

관련 권장 사항:

Javascript 타이머 예제 코드

Javascript 타이머 심층 탐구

자바스크립트 타이머의 전체 예

자바스크립트 타이머와 최적화된 취소 타이머 방식

위 내용은 JavaScript의 타이머 원리 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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