javascript 단일 스레드
JavaScript의 단일 스레드는 그 목적과 관련이 있습니다. 브라우저 스크립팅 언어인 JavaScript의 주요 목적은 사용자와 상호 작용하고 DOM을 조작하는 것입니다. 이는 단일 스레드만 가능하다는 것을 결정합니다. 그렇지 않으면 매우 복잡한 동기화 문제가 발생합니다. 예를 들어 JavaScript에 두 개의 스레드가 동시에 있다고 가정해 보겠습니다. 한 스레드는 특정 DOM 노드에 콘텐츠를 추가하고 다른 스레드는 해당 노드를 삭제합니다. 이 경우 브라우저는 어떤 스레드를 사용해야 합니까? 따라서 복잡성을 피하기 위해 JavaScript는 탄생부터 단일 스레드를 사용했으며 이는 언어의 핵심 기능이 되었으며 앞으로도 변하지 않을 것입니다.
대기열 작업
단일 스레드는 모든 작업을 대기열에 넣어야 하며 이전 작업이 완료될 때까지 다음 작업이 실행되지 않음을 의미합니다. 이전 작업이 오래 걸리면 다음 작업은 기다려야 합니다.
비동기 이벤트 중심
마우스 클릭 이벤트, 창 크기 드래그 이벤트, 타이머 트리거 이벤트, XMLHttpRequest 완료 콜백 등과 같은 브라우저의 많은 동작은 비동기식입니다. 비동기 이벤트가 발생하면 이벤트 큐에 들어갑니다. 브라우저에는 대규모 이벤트 큐를 폴링하고 이벤트를 처리하는 대규모 내부 메시지 루프인 이벤트 루프가 있습니다. 예를 들어, 브라우저는 현재 onclick 이벤트를 처리 중입니다. 이때 다른 이벤트(예: window onSize)가 발생합니다. 이 비동기 이벤트는 처리를 기다리기 위해 이벤트 큐에 배치됩니다. 완료되었으며 무료 이벤트입니다.
이벤트 루프
JavaScript는 단일 스레드이지만 브라우저는 단일 스레드가 아닙니다
브라우저에는 최소한 다음 프로세스 중 일부가 포함됩니다
1. 브라우저 GUI 렌더링 스레드
2.JavaScript 엔진 스레드
3. 브라우저 예약 트리거 스레드
4. 브라우저 이벤트 트리거 스레드
5. 브라우저 http 비동기 요청 스레드
JavaScript 엔진은 단일 스레드이기 때문에 코드가 먼저 대기열에 푸시된 다음 선입선출 방식으로 엔진에 의해 실행됩니다. 이벤트 처리 기능과 타이머 실행 기능도 이 큐에 대기하며 무한 루프를 사용하여 큐의 선두에서 계속해서 기능을 꺼내 실행합니다.
요약하자면, js는 단일 스레드이지만 브라우저는 다중 스레드입니다. 비동기 작업이 발생하면 브라우저는 이벤트 루프에 비동기 콜백을 넣습니다. 이벤트 루프 읽기
타이머 원리
타이머 사용법
setTimeout(fn, 지연)
setInterval(fn, 지연)
fn은 함수 또는 문자열이고, Delay는 지연 시간이며, 단위는 밀리초입니다
다음과 같은 주의사항이 있습니다
1.fn은 문자열일 수 있지만 이런 방식으로 사용하는 것은 절대 권장되지 않습니다
2. in.fn 함수에 이것이 있으면 실행 시 창을 가리킵니다
js 싱글 쓰레드와 이벤트 루프를 이해한다면 타이머의 원리도 이해하기 쉽습니다
타이머가 설정된 경우 지연 시간에 도달하면 브라우저는 지연된 실행 이벤트를 이벤트 루프에 넣습니다. 시간이 다 되면 js 스레드가 유휴 상태이면 실행됩니다(그래서 정확성이 떨어짐). 타이머가 정확하지 않습니다)
폴링 함수에서 setTimeout과 setInterval의 차이점을 소개하는 글을 자주 읽었는데 코드는 다음과 같습니다
가 한 번에 실행됩니다.
테스트 결과 ie, ff, chrome, Opera, Safari 아래에서는 setInterval이 일정한 간격으로 설정되어 있는 것으로 확인되었습니다테스트 코드는 다음과 같습니다
setTimeout(함수(){
디버거;
},10)
중단점에서는 1이 하나만 인쇄되었습니다.
타이머 정확도 문제
js는 싱글 스레드이기 때문에 바쁜 경우 타이머가 확실히 부정확해지고, 점점 길어질 것입니다. 이에 대한 해결책도 없고 해결책도 없는 것 같습니다
또 다른 정밀도 문제는 최소 간격 setTimeout(fun,0)
js 스레드가 사용 중이지 않으면 0초 후에 즉시 실행될 수 없습니다. 항상 최소 간격이 있으며 이는 브라우저마다 다릅니다.
w3c 표준을 언급한 기사를 읽었습니다. 타이머의 최소 실행 시간은 4ms입니다. 소스를 찾을 수 없고 확인할 수 없습니다. ! !
타이머 관련 일부 최적화
타이머를 만들 때 여전히 일부 최적화가 있을 수 있습니다
1. 예를 들어 window.onresize를 바인딩하면 브라우저가 확대될 때 매우 자주 실행되므로 실행이 지연될 수 있으며, 잦은 실행을 줄이기 위해 다음 실행이 발생하면 지워집니다
의사코드는 다음과 같습니다
3. 타이머가 필요한 장소가 여러 곳일 경우, 가장 작은 타이머를 기준으로 시간 간격을 정하고, 그 시간이 되면 배열에 삽입합니다. 간격에 도달하면 배열이 순회됩니다.
간단한 데모