JavaScript 모델 동시 실행 정보
13371 단어 Node.jsJavaScript
개요
JavaScript와 많은 언어의 차이점 중 하나는 이벤트 순환을 바탕으로 하는 병렬 실행 모델이다.이것은 JavaScript 자체라기보다는 브라우저의 구조와 관련이 있습니다.
이번에 나는 그것을 써 보려고 한다.
생산라인 시간
DN 맵을 대여하면 JavaScript의 생산 라인 시간은 다음과 같은 요소로 구성됩니다.하나하나 설명하다.
쌓다
쌓아. 쌓아.이번 주제와는 좀 동떨어져 있어서 생략합니다.
창고
JavaScript에서 처리를 호출하면 호출 스택이 쌓입니다.
JavaScript는 단일 스레드이므로 한 번에 하나의 처리만 수행할 수 있습니다.예를 들어 다음 호출 함수의 처리를 고려한다.
function subA() { console.log('A'); }
function subB() { console.log('B'); }
function main() {
subA();
subB();
}
main();
다음과 같은 스택이 생성됩니다.
main 프레임main에서 호출된 subA 프레임 subA의 실행이 완료되면subA 프레임이 스택에서 팝업main에서 호출된 subB 프레임 subB의 실행이 완료되면subB 프레임이 스택에서 팝업main 프레임이 스택에서 팝업줄을 서다
JavaScript의 대기열은 다음 처리 목록이라고 할 수 있습니다.
여기에서
setTimeout 코드를 사용합니다.function setTimeoutCallback() {
console.log('A');
}
function subA() {
setTimeout(setTimeoutCallback, 7000)
}
function subB() { console.log('B'); }
function main() {
subA();
subB();
}
main();
다음과 같은 스택과 대기열이 생성됩니다.
main 프레임main에서 호출된 subA 프레임 subA에서 호출된 setTimeout 프레임 setTimeout의 실행이 완료되면setTimeout 프레임이 스택에서 꺼집니다.브라우저 측면에서 타이머 계산을 시작합니다.main에서 호출된 subB 프레임 subB의 실행이 완료되면subB 프레임이 스택에서 팝업4의 타이머가 끝나면 브라우저는 이벤트를 대기열에 추가합니다main 프레임이 스택에서 팝업4에서 타이머의 처리는 JavaScript의 주 라인을 떠났고 대기열의 구조로 인해 처리가 막히지 않고 있습니다.이 밖에 연속 호출도 고려할 수 있다
setTimeout.function setTimeoutCallback() {
console.log('A');
}
function subA() {
setTimeout(setTimeoutCallback, 7000)
setTimeout(setTimeoutCallback, 7000)
setTimeout(setTimeoutCallback, 7000)
setTimeout(setTimeoutCallback, 7000)
setTimeout(setTimeoutCallback, 7000)
}
function subB() { console.log('B'); }
function main() {
subA();
subB();
}
main();
다음과 같은 스택과 대기열이 생성됩니다.
위에서 말한 바와 같이 호출 자체는 함수이지만 처리 자체는 브라우저 API가 동시에 실행하고 완성된 것부터 자바스크립트 측의 대기열에 쌓인다.
이것은 스레드 등 실현 가능한
並列(parallel) 처리라고 할 수는 없지만, 실제 처리를 JavaScript가 실행될 때 제외하고, 並行(concurrent) 에서 처리한다고 할 수 있다.並行/並列/非同期/ノンブロッキング 부근은 오해를 받기 쉬우므로 다른 것을 통제하는 것이 좋다.이븐트루프
위에서 언급한 바와 같이 대기열을 검출할 수 있는 구조를 이벤트 순환이라고 한다.이벤트 순환은 이벤트의 구현을 기다리는 중 하나입니다. MDN 예시를 빌려쓰면 다음과 같습니다.
while(queue.waitForMessage()){
queue.processNextMessage();
}
단홍색의 이벤토르프는 동시에 발생하는 사건을 가볍게 처리하기에 적합하다.프로세스가 대량으로 상승하여 메모리와 상하문 스위치가 처리가 무거워지는 것을 방지할 수 있기 때문이다.(단, 대량 계산 등 시간 소모 처리는 잘하지 못하며 처리가 끝날 때까지 후속 처리를 막는다).JavaScript 이외에 단일 스레드 이벤트 구동 구조를 사용하는 제품 중에서nginx는 매우 유명하다.
nginx는 상기 방침으로 C10K 문제, Node를 해결할 계획이다.가끔 js가 그 상하문에서 하는 말을 볼 수 있다.그러나 원래 자바스크립트는 90년대 인터넷 브라우저와 같은 충분한 자원이 없는 환경을 위해 개발된 언어였다.나는 정확한 배경은 유한한 CPU에서 약간의 진지한 행동을 실현한 것이 단타홍+이빈트루프의 구조라고 생각한다.
즉, 이벤트 순환 체계 구조는 브라우저에서 발생하는 대량의 이벤트 (적어도 당시) 를 처리하는 가장 좋은 용례라고 할 수 있다.이제 Go처럼 경량 라인을 사용하면 선이 더 좋아질 수 있습니다.
응용 예
다음은 우리가 실제적으로 유용한 예들을 좀 봅시다.
이것은 매우 유명한 예로
setTimeout(func, 0) 를 사용하여 처리를 대기열에 내보내 그리는 시간을 가속화하는 방법이 있다.예를 들어, 다음과 같이 DOM의 변경 처리 후에는 상당한 시간이 소요됩니다.// DOMの変更処理
var target = document.getElementById('target');
target.textContent = 'updated';
// 時間のかかる処理
var calcResult;
function longTask() {
for (var i = 0; i < 1000000000; i++) {
calcResult = i * 3;
}
}
longTask();
만약 네가 이런 코드를 썼다면, 실제 화면 변경은 즉각 진행되지 않을 것이다.브라우저가 그림을 그리기 전에 10억 번의 순환이 라인을 채우기 때문에 그림이 늦어진다.메인 라인을 보면 longTask 약 4초가 걸리기 때문에 사용자는 상호작용을 기다리겠지.
그리기를 가속화하는 방법 중 하나는 "
setTimeout(func, 0) 처리를 대기열로 잠시 미루는 것"등이다.// DOMの変更処理
var target = document.getElementById('target');
target.textContent = 'updated';
// 時間のかかる処理
var calcResult;
window.setTimeout(function longTask() {
for (var i = 0; i < 1000000000; i++) {
calcResult = i * 3;
}
}, 0)
이렇게 하면 먼저 회화 처리를 할 수 있기 때문에 성능을 개선할 수 있다.
그러나 후속 처리가 막히지 않기 때문에 처리된 디스플레이로 표시하거나 Worker 등을 사용하는 것이 좋습니다.아무래도 구조를 이해하는 것도 예상치 못한 사고에 대한 위험부담이 될 수 있다.
총결산
이번에는 JavaScript의 동시 실행 모델을 소개합니다.아래의 말을 듣고 깊은 인상을 남길 수 있다면 이 기사의 총결이 아닐까 싶습니다.
참고 자료
Reference
이 문제에 관하여(JavaScript 모델 동시 실행 정보), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/okmttdhr/items/dc3cfd0e12de91553fe6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)