약 반년 전에 setTimeout과 setInterval에 대한 기사를 냈는데, 지금 다시 자세히 살펴보니 실제로는 부족한 점과 오류가 많다는 것을 알게 되었습니다. 실제로 setTimeout과 setInterval은 문자 그대로 이해하는 것만큼 간단하지 않습니다. 이 두 가지 방법을 진정으로 익히고 이해하려면 JavaScript의 단일 스레드 메커니즘부터 시작해야 합니다.
【본론으로 바로 넘어가기】 setTimeout과 setInterval은 어떻게 작동하나요?
우리는 js가 단일 스레드에서 실행된다는 것을 알고 있습니다. 따라서 실제로 setTimeout 및 setInterval의 소위 "비동기 호출"은 코드의 실행 대기열에 코드 세그먼트를 삽입하여 실제로 구현됩니다.
삽입 시점은 어떻게 계산하나요? 당연히 우리는 타이머라고 부르는 것을 사용해야 합니다. setTimeout 및 setInterval을 실행하면 타이머는 사용자가 설정한 시간을 기준으로 코드 삽입 지점을 "정확하게" 찾습니다. 대기열이 삽입 지점까지 "정상적으로" 실행되면 타이머 콜백이 트리거됩니다. 이는 우리가 설정한 콜백 함수입니다.
function fn() {
/*
여기에 일부 코드가 있습니다.
*/
setTimeout(function() {alert( 'ok!')},1000);
}
위의 예는 일반적인 사용법이므로 이해하기 쉽습니다. 하지만 타이머가 정말 그렇게 정확할 수 있을까요? 코드 대기열의 실행이 실제로 그렇게 정상적일 수 있습니까?
【잔디를 자르세요】 소위 "비동기"를 다시 이해하세요
방금 배운 것처럼 실제로 setTimeout과 setInterval은 코드를 삽입하여 지연된 코드 실행(또는 비동기 실행)을 구현합니다. 코드 대기열). 그러나 실제로 소위 비동기식은 단지 환상일 뿐이며 스레드에서도 실행됩니다!
그러면 코드 삽입 지점 이전의 코드 실행 시간이 setTimeout 또는 setInterval에 전달된 설정 시간을 초과하면 어떻게 되는지 궁금합니다. 이 코드를 살펴보겠습니다.
function fn( ) {
setTimeout(function(){alert('내가 보이나요?');},1000)
while(true) {}
}
you 이 코드의 실행 결과는 무엇이라고 생각하시나요? 대답은 경고가 결코 나타나지 않는다는 것입니다.
이게 왜요? while 코드가 실행되지 않았기 때문에 나중에 삽입된 코드는 절대 실행되지 않습니다.
결론적으로 말하자면, JS는 결국 싱글스레드 제품입니다. 아무리 "비동기적"이라고 해도 단일 스레드 장벽을 돌파하는 것은 불가능합니다. 따라서 많은 "비동기 호출"(Ajax 포함)은 실제로는 "의사 비동기"입니다. 이러한 개념을 이해한다면 setTimeout과 setInterval을 이해하는 것은 어렵지 않을 것입니다.