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.)