setInterval 과 setTimeout 의 성능 문제
3216 단어 JavaScript
이유 중 하나: setInterval 코드 오류 무시
setInterval 은 자신 이 호출 한 코드 가 잘못 되 었 는 지 에 대해 무관심 한 습관 이 있다.
setInterval 에서 실 행 된 코드 가 어떤 이유 로 잘못 되면 이 코드 를 계속 호출 할 것 이라는 얘 기다.
우 리 는 아래 의 이 예 를 분석 해 보 자.
function a() {
try {
a.error();
} catch(e) {
throw(e);
}
}
setInterval(a, 2000);
function b() {
try {
b.error();
} catch (e) {
throw(e);
}
setTimeout(b, 1000);
}
setTimeout(b, 2000);
원인 2: setInterval 네트워크 지연 무시
일정 시간 마다 Ajax 를 통과 한다 고 가정 해 봐. 서버 에 문의 하여 새로운 데이터 가 있 는 지 확인 하 세 요. (주의: 만약 당신 이 정말 이렇게 한다 면 아마 당신 이 잘못 한 것 같 습 니 다. "보상 성 폴 링" (backoff polling) 을 사용 하 는 것 을 권장 합 니 다.일부 원인 (서버 과부하, 임시 차단, 데이터 급증, 사용자 대역 폭 제한) 으로 인해 당신 의 요청 은 생각 보다 오래 걸 립 니 다.하지만 setInterval 은 개의 치 않 는 다.이것 은 여전히 정 해진 시간 에 따라 요청 을 계속 실행 합 니 다. 최종 적 으로 클 라 이언 트 네트워크 대기 열 은 Ajax 호출 을 가득 채 울 것 입 니 다.
우 리 는 아래 의 이 예 를 분석 해 보 자.
let n = 0, t = 0, u = 0, i;
const s = 'Stopping after 25 requests, to avoid killing jsfiddle’s server';
function a() {
$.post('***', () => {
--n;
});
++n;
++t;
$('#reqs').html(n + ' a() requests in progress!');
if (t > 25) {
clearInterval(i);
$('#reqs').html(s);
}
}
function b() {
++u;
$.post('***', () => {
$('#req2').html('b(): ' + new Date().toString());
if (u <= 25) {
setTimeout(b, 500);
} else {
$('#req2').html(s);
}
});
}
i = setInterval(a, 500);
setTimeout(b, 500);
원인 3: setInterval 은 실행 간격 을 보장 하지 않 습 니 다.
setTimeout 과 달리 시간 간격 이 되면 코드 가 실 행 될 수 있다 는 보장 은 없습니다.
만약 당신 이 호출 한 함수 가 비교적 오 랜 시간 이 걸 려 야만 완성 할 수 있다 면, 일부 호출 은 직접 무 시 될 것 입 니 다.
function slow() {
$.ajax({
url: '/echo/html/',
async: false,
data: {
delay: 1
},
complete: function () {
}
});
$('#reqs').text(~~((new Date() - start) / 100) + ' expected, ' + iters + ' actual');
if (iters++ > 4) {
$('#reqs').append('
Stopping after 5 iterations');
clearInterval(iv);
}
}
let iv = setInterval(slow, 100);
let start = +new Date();
let iters = 0;
setTimeout 은 이 문 제 를 해결 할 수 있 습 니 다.
setInterval 을 사용 하기 보 다 는 적당 한 시간 에 setTimeout 을 통 해 함수 자 체 를 호출 하 는 것 이 좋 습 니 다.
앞의 두 예제 에서 setInterval 을 사용 하 는 함수 a 가 모두 잘못 되 었 고 setTimeout 을 사용 하 는 함수 b 는 잘 표현 되 었 습 니 다.
만약 간격 이 같다 는 것 을 보증 해 야 한다 면 어떻게 합 니까?
이벤트 의 '등 속' 이 촉발 되 는 것 을 확실히 보장 하려 면 원 하 는 지연 으로 지난번 호출 에 걸 린 시간 을 뺀 다음 에 얻 은 차 이 를 지연 동적 으로 setTimeout 에 지정 할 수 있 습 니 다.하지만 주의해 야 할 것 은 자 바스 크 립 트 의 타 이 머 는 정확 하지 않다 는 점 이다.따라서 절대적 인 '평균' 지연 을 받 을 수 없습니다. setInterval 을 사용 하 더 라 도 안 됩 니 다. 원인 이 많 습 니 다 (예 를 들 어 쓰레기 회수, JavaScript 는 단일 스 레 드 입 니 다. 등등).또한 현재 브 라 우 저 는 최소 시간 초과 시간 을 4ms 에서 15ms 사이 로 고정 합 니 다.그 러 니 조금의 오차 도 없다 고 기대 하지 마라.
마지막 으로 마 이 클 은 setInterval 을 사용 하 느 냐 setTimeout 을 사용 하 느 냐 에 따라 먼저 프로젝트 의 기능 요구 에 따라 기능 을 실현 하 는 것 이 가장 중요 한 임무 라 고 주장 했다.만약 에 둘 다 사용 할 수 있 는 상황 에서 setTimeout 을 사용 하여 재 귀적 호출 을 실현 하여 더욱 좋 은 성능 최적화 를 실현 할 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
기초 정리 - 1문자 (String) 숫자 (Number) 불린 (Boolean) null undefined 심볼 (Symbol) 큰정수 (BigInt) 따옴표로 묶어 있어야 함 Not-A-Number - 숫자 데이터 / 숫자로 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.