브 라 우 저의 이벤트 순환 (Event Loop) 은 무엇 입 니까?

본 고 는 브 라 우 저의 이벤트 순환 을 둘러싸 고 있 으 며, node. js 는 자신의 또 다른 이벤트 순환 메커니즘 을 가지 고 있 으 며, 본 고의 토론 범위 에 있 지 않다.인터넷 상의 많은 관련 기술 문장 이 언급 되 었 다.process.nextTicksetImmediate 두 node. js 의 API 는 토론 하지 않 습 니 다.
먼저 HTML 표준 에 대한 일련의 설명 을 보십시오.
조 화 를 위해 (event), (user interaction), (script), (rendering), (networking) 등 사용자 에이전트 (user agent) 를 사용 해 야 합 니 다. (event loops)。
두 가지 이벤트 순환 이 있 습 니 다. 하 나 는 (browsing context) 이 고 다른 하 나 는 worker (web worker) 입 니 다.
이제 우 리 는 브 라 우 저가 실 행 될 때 이벤트 순환 이라는 메커니즘 이 있다 는 것 을 알 게 되 었 다.
하나의 이벤트 가 하나 이상 순환 합 니 다. (task queues)。작업 대기 열 은 task 의 서열 표 입 니 다. 이 task 는 다음 작업 에 대응 하 는 알고리즘 입 니 다. Events, Parsing, Callbacks, Using a resource, Reacting to DOM manipulation.
모든 임 무 는 특정한 (task source) 에서 나온다.특정한 작업 원본 에서 왔 고 특정한 이벤트 순환 에 속 하 는 모든 작업 은 같은 작업 대기 열 에 가입 해 야 하지만, 서로 다른 작업 원본 에서 온 작업 은 다른 작업 대기 열 에 놓 일 수 있 습 니 다.
예 를 들 어 사용자 에이 전 트 는 마우스 와 키보드 이 벤트 를 처리 하 는 작업 대기 열 이 있 습 니 다.사용자 에이 전 트 는 다른 대기 열 보다 3 / 4 의 실행 시간 을 더 줄 수 있 으 며, 다른 작업 대기 열 이 굶 어 죽지 않도록 상호작용 의 응답 을 확보 할 수 있 으 며, 작업 대기 열의 이 벤트 를 함부로 처리 하지 않 습 니 다.
모든 이벤트 순환 에는 진입 microtask 검사 점 (performing a microtask checkpoint) 의 flag 표지 가 있 습 니 다. 이 표 지 는 처음에 false 입 니 다.그것 은 'microtask 검사 점 에 들 어가 기' 알고리즘 을 반복 적 으로 호출 하 는 데 사용 된다.
요약 하면 하나의 이벤트 순환 에는 여러 개의 작업 대기 열 (task queues) 이 서로 다른 작업 소스 에서 왔 습 니 다. 모든 작업 대기 열 에 있 는 임 무 는 선진 적 인 순서대로 엄 격 히 수행 되 지만 서로 다른 작업 대기 열 에 있 는 작업 의 수행 순 서 는 확실 하지 않 습 니 다.내 가 이해 하 는 바 에 의 하면 브 라 우 저 는 스스로 다른 작업 대기 열 을 예약 할 것 이다.인터넷 에서 많은 글 들 이 macrotask 라 는 개념 을 언급 하 는데 사실은 기준 에서 논술 한 task 을 대체 한 것 을 말한다.
기준 은 microtask 의 개념, 즉 마이크로 미 션 도 함께 언급 했다.표준 적 으로 논 술 된 이벤트 순환 의 프로 세 스 모델 을 보십시오.
  • 현재 실행 할 작업 대기 열 을 선택 하고 작업 대기 열 에 가장 먼저 들 어 가 는 작업 을 선택 하 십시오. 선택 할 수 있 는 작업 이 없 으 면 microtask 의 실행 절차 로 이동 합 니 다.
  • 이벤트 순환 의 현재 실행 작업 을 선택 한 작업 으로 설정 합 니 다.
  • 임 무 를 수행 합 니 다.
  • 이벤트 순환 의 현재 실행 작업 을 null 로 설정 합 니 다.
  • 실 행 된 작업 을 작업 대기 열 에서 제거 합 니 다.
  • microtasks 절차: microtask 검사 점 (performing a microtask checkpoint) 에 들 어 갑 니 다.
  • 업데이트 인터페이스 렌 더 링.
  • 첫 걸음 으로 돌아간다.

  • microtask 검사 점 에 들 어 갈 때 사용자 에이 전 트 는 다음 절 차 를 수행 합 니 다.
  • microtask 검사 점 에 들 어 가 는 표 지 를 true 로 설정 합 니 다.
  • 이벤트 가 순환 하 는 마이크로 작업 대기 열 이 비어 있 지 않 을 때: microtask 대기 열 에 가장 먼저 들 어 가 는 microtask 를 선택 하 십시오.이벤트 순환 의 현재 실행 작업 을 선택 한 microtask 로 설정 합 니 다.microtask 실행 하기;이벤트 순환 의 현재 실행 작업 을 null 로 설정 합 니 다.실행 이 끝 난 microtask 를 microtask 대기 열 에서 제거 합 니 다.
  • 해당 이벤트 가 순환 하 는 모든 환경 설정 대상 (environment settings object) 에 대해 어떤 promise 가 rejected 인지 알려 줍 니 다.
  • indexedDB 의 업 무 를 정리 합 니 다.
  • microtask 검사 점 에 들 어 가 는 표 지 를 false 로 설정 합 니 다.

  • 이제 알았어.이벤트 순환 에서 사용자 에이 전 트 는 task 대기 열 에서 순서대로 task 를 가 져 와 실행 합 니 다. 하나의 task 를 실행 할 때마다 microtask 대기 열 이 비어 있 는 지 확인 합 니 다. (하나의 task 를 실행 한 구체 적 인 표 지 는 함수 실행 스 택 이 비어 있 는 것 입 니 다) 비어 있 지 않 으 면 있 는 microtask 를 한꺼번에 실행 합 니 다.다음 순환 에 들 어가 서 task 대기 열 에서 다음 task 를 가 져 와 서 실행...
    그렇다면 어떤 행동 이 task 나 microtask 에 속 합 니까?기준 은 논술 되 지 않 았 으 나 각종 기술 문장의 총 결 은 다음 과 같다.
  • macrotasks: script (전체 코드), setTimeout, setInterval, setImmediate, I / O, UI rendering
  • microtasks: process. nextTick, Promises, Object. observe (폐기), MutationObserver
  • 예 를 들 어 보 겠 습 니 다.
    console.log('script start');
    
    setTimeout(function() {
      console.log('setTimeout');
    }, 0);
    
    Promise.resolve().then(function() {
      console.log('promise1');
    }).then(function() {
      console.log('promise2');
    });
    
    console.log('script end');

    (코드 는 Tasks, microtasks, queues and schedules 에서 왔 습 니 다. 원문의 코드 시각 화 실행 절 차 를 보 는 것 을 추천 합 니 다)
    테스트 한 브 라 우 저가 지원 하 는 Promise 가 Promise / A + 표준 을 지원 하지 않 거나 다른 Promise poly fill 을 사용 했다 면 실행 결과 에 차이 가 있 을 수 있 습 니 다.
    실행 결 과 는:
    script start
    script end
    promise1
    promise2
    setTimeout

    과정 을 설명 하 다.
  • 처음에 task 대기 열 에 script 만 있 었 으 면 script 에 있 는 모든 함수 가 함수 에 넣 어 스 택 을 실행 하고 코드 는 순서대로 실 행 됩 니 다.

  • 이 어 setTimeout 를 만 났 습 니 다. 그 역할 은 0 ms 후 리 셋 함 수 를 task 대기 열 에 넣 는 것 입 니 다. 즉, 이 함 수 는 다음 이벤트 순환 에서 실 행 됩 니 다. (이때 setTimeout 실행 이 끝나 면 되 돌아 갑 니 다.)
  • 이어서 만 났 습 니 다 Promise. 앞에서 말 한 Promise 는 microtask 에 속 하기 때문에 첫 번 째. then () 은 microtask 대기 열 에 넣 습 니 다.
  • 모든 script 코드 가 실 행 된 후에 함수 실행 스 택 이 비어 있 습 니 다.microtask 대기 열 을 검사 하기 시 작 했 습 니 다. 이 때 대기 열 이 비어 있 지 않 습 니 다. then () 의 리 셋 함수 출력 'promise 1' 을 실행 합 니 다. then () 이 되 돌아 오 는 것 은 여전히 promise 이기 때문에 두 번 째. then () 은 microtask 대기 열 에 넣 어 계속 실행 합 니 다. 'promise 2' 를 출력 합 니 다.
  • 이때 microtask 대기 열 이 비어 있 습 니 다. 다음 이벤트 순환 에 들 어가 task 대기 열 에서 setTimeout 의 리 셋 함 수 를 발 견 했 습 니 다. 리 셋 함수 출력 'setTimeout' 을 즉시 실행 하고 코드 가 실 행 됩 니 다.

  • 더 재 미 있 는 예 를 계속 보 세 요.
    HTML 코드:

    JavaScript代码:

    // Let's get hold of those elements
    var outer = document.querySelector('.outer');
    var inner = document.querySelector('.inner');
    
    // Let's listen for attribute changes on the
    // outer element
    new MutationObserver(function() {
      console.log('mutate');
    }).observe(outer, {
      attributes: true
    });
    
    // Here's a click listener…
    function onClick() {
      console.log('click');
    
      setTimeout(function() {
        console.log('timeout');
      }, 0);
    
      Promise.resolve().then(function() {
        console.log('promise');
      });
    
      outer.setAttribute('data-random', Math.random());
    }
    
    // …which we'll attach to both elements
    inner.addEventListener('click', onClick);
    outer.addEventListener('click', onClick);

    (코드 는 Tasks, microtasks, queues and schedules, 원문의 코드 시각 화 실행 절 차 를 보 는 것 을 추천 합 니 다) 내 상 자 를 클릭 한 결 과 는 다음 과 같 습 니 다.
    click
    promise
    mutate
    click
    promise
    mutate
    timeout
    timeout

    과정 설명: inner 를 누 르 면 'click' 을 출력 합 니 다. Promise 와 outer 속성 을 설정 하면 Promise 와 MutationObserver 를 microtask 대기 열 에 순서대로 밀어 넣 고 setTimeout 은 task 대기 열 에 밀어 넣 습 니 다.이 때 실행 스 택 이 비어 있 습 니 다. 뒤에 거품 트리거 가 있 지만 이 때 microtask 대기 열 이 먼저 실 행 됩 니 다. 따라서 'promise' 와 'mutate' 를 순서대로 입력 하 십시오.다음 사건 의 거품 이 다시 사건 을 촉발 시 키 는 과정 은 시작 과 같다.이 어 코드 실행 이 완료 되 었 습 니 다. 이 때 다음 이벤트 순환 에 들 어가 task 대기 열 에 있 는 작업 을 수행 하고 'timeout' 두 개 를 출력 합 니 다.
    자, 이것 을 이해 했다 면 지금 사건 이 촉발 하 는 방식 을 바 꿔 보 세 요.위의 코드 뒤에 덧 붙 여 주세요.
    inner.click()

    어떻게 달라 질 지 생각 해 봐.
    실행 결과:
    click
    click
    promise
    mutate
    promise
    timeout
    timeout

    이 차 이 를 만 든 결 과 는 무엇 일 까?첫 번 째 click 이 벤트 를 처음 실행 한 후 함수 실행 스 택 이 비어 있 지 않 기 때 문 입 니 다.구체 적 인 코드 실행 설명 은 Tasks, microtasks, queues and schedules 를 볼 수 있 습 니 다.
    본문 참고: html. spec. whatwg. org difference - between - javascript - macrotask - and - microtaskEvent loop
    벽 이 갈 라 지 는 것 은 HTML 기준 에서 설명 한 Event Loop 을 읽 는 것 을 권장 합 니 다. 지적 과 건 의 를 환영 합 니 다.

    좋은 웹페이지 즐겨찾기