Settimeout
함수 설명
setTimeout(functionRef, delay, param1, param2, /* …, */ paramN)
첫 번째 인자에 넣은 함수를 딜레이 이후 실행해준다. 뒤의 파라미터들은 함수에 전달해주는 매개변수이다.
delay 값을 숫자값이 아니라 “1000” 과 같은식으로 전달할 경우 1초로 자동으로 변경된다. 잘못된 값을 넣으면 자동으로 0초로 변환된다.
반환 값은 timeoutID를 받으며 이는 clearTimeout() 을 통해 타입아웃을 취소할 수 있다.
This 문제
setTimeout은 다른 excution context에서 실행된다. 따라서 자바스크립트의 this 바인딩 특성상 이 값이 바뀔 수 있어 문제가 발생할 수 있다.
[정상 동작]
const myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
console.log(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
위 코드의 경우 myMethod를 호출할 때 this가 myArray로 설정되어 정상적으로 동작한다.
setTimeout(myArray.myMethod, 1.0 * 1000); // 1초 후 "[object Window]" 기록
setTimeout(myArray.myMethod, 1.5 * 1000, "1"); // 1.5초 후 "undefined" 기록 (window["1"] === undefined)
하지만 setTimeout의 경우 타임아웃 만료 시점에 this가 따로 설정되지 않아 기본값인 window 객체를 가리키게 되어 예상대로 동작하지 않는다.
이러한 문제는 클로저, bind() 를 통해 해결할 수 있다.
Delay가 부정확한 문제
- setTimeout 호출이 5번 이상 중첩된경우 최소 4ms의 지연을 준다.
let start = Date.now();
let times = [];
setTimeout(function run() {
times.push(Date.now() - start);
if (start + 100 < Date.now()) {
console.log(times)
return
}
setTimeout(run);
});
// 출력 [1, 1, 1, 1, 9, 14, 18, 23, 27...
setInterval에도 동일하게 적용된다.
이러한 제약은 브라우저에서만 존재하며 서버에서는 process.nextTick, setImmediate사용을 통해 지연 없이 실행할 수 있다.
- 백그라운드에서의 지연
백그라운드에서의 부하를 경감하기 위해 브라우저는 비활성 탭에 지연 시간을 강제로 부여한다. (브라우저 마다 다름)
단 소리를 재생중일 때에는 지연을 강제하지 않는 경우도 있다.
- 사용자 추적 스크립트에 대한 쓰로틀링 적용
소셜 네트워크같은곳에서 사용하는 사용자의 방문기록, 행동등을 기록하는 스크립트라고 인식하였을 때 백그라운드라면 이러한 스크립트에 대해 첫 로드 이후 30초가 지났을 때 10초의 쓰로틀링을 적용한다. (브라우저 마다 다름)
- callStack이 비어있지 않을 경우
function foo() {
console.log("foo 호출");
}
setTimeout(foo, 0);
console.log("setTimeout 완료");
//setTimeout 완료
//foo 호출
- webExtension의 경우
extension의 setTimeout은 신뢰할 수 없기때문에 extension에서는 alarms API 사용을 권장하고 있다.
- 최대 지연시간을 초과한 경우
브라우저들에서 내부적으로 32비트의 정수 값으로 지연 시간을 저장한다. 따라서 2,147,483,647ms(약 24.8일) 초과의 값을 지정할 경우 오버플로우가 발생해 타입아웃이 즉시 만료된다.
- 페이지 로드 중 타임아웃 지연
현재 탭이 로드 중일 때 타이머를 지연하는 브라우저도 있다.
'javascript' 카테고리의 다른 글
EventLoop에 대한 완벽하지는 않지만 자세한 설명 (0) | 2024.05.03 |
---|---|
RequestAnimationFrame이란 (1) | 2024.04.25 |
Viewport (0) | 2024.04.05 |
Builder를 위한 Path parser 구현 후기 (1) | 2024.01.09 |
Promise.race를 응용한 긴 비동기 작업 필터링 방법 (1) | 2023.12.22 |