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의 동시 실행 모델을 소개합니다.아래의 말을 듣고 깊은 인상을 남길 수 있다면 이 기사의 총결이 아닐까 싶습니다.
  • 스택, 대기열
  • 단식 레드, 이본 트루프
  • 병렬
  • 도움이 됐으면 좋겠어요.

    참고 자료

  • Concurrency model and Event Loop - JavaScript | MDN
  • JavaScript Event Loop Explained – Frontend Weekly – Medium
  • JavaScript 스레드 병렬 실행 환경
  • 편의점에서 볼 수 있는 비블로거 IO-응사 블로그.
  • 이벤트 루프 없는 고성능 – C10K 질문 응답 시작
  • 이벤트가 스레드에 비해 왜 안 되는지 (Why Events Are A Bad Idea)|yunabe.jp
  • 좋은 웹페이지 즐겨찾기