이벤트 루프 컨텍스트 내의 마이크로태스크와 매크로태스크의 차이
Promise/A+ 사양을 읽은 지 얼마 안 되어 마이크로태스크와 매크로태스크라는 용어를 발견했습니다.http://promisesaplus.com/ #notes를 참조하십시오.
처음 들어보는 용어인데 뭐가 다른지 궁금하네요.
이미 웹에서 몇 가지 정보를 찾았지만, 제가 발견한 것은 w3.org Archives의 이 게시물뿐입니다(이것으로는 차이를 설명할 수 없습니다). http://lists.w3.org/Archives/Public/public-nextweb/2013Jul/0018.html
또, 「macrotask」라고 불리는 npm 모듈을 발견했습니다.https://www.npmjs.org/package/macrotask 에서도, 그 차이가 정확히 무엇인지는 명확하지 않습니다.
https://html.spec.whatwg.org/multipage/webappapis.html#task-queue 및 https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint에서 설명한 바와 같이 이벤트루프와 관련이 있는 것으로 알고 있습니다.
이 WHATWG 사양에 따라 이론적으로 제가 직접 차이를 추출할 수 있을 것입니다.하지만 전문가의 짧은 설명으로 다른 사람들도 혜택을 받을 수 있을 거라고 확신해요.
이벤트 루프의 1회 실행 시 매크로태스크 큐에서 처리되는 태스크는 딱1개입니다(이 큐는 WHATWG 사양에서는 태스크큐라고 불립니다).이 매크로태스크가 완료되면 사용 가능한 모든 마이크로태스크가 처리됩니다.즉, 동일한 실행 사이클 내에 처리됩니다.이러한 마이크로태스크가 처리되는 동안 마이크로태스크 큐가 모두 소진될 때까지 더 많은 마이크로태스크를 큐잉할 수 있습니다.
이것의 실질적인 결과는 무엇입니까?
마이크로태스크가 다른 마이크로태스크를 재귀적으로 큐잉하는 경우 다음 매크로태스크가 처리될 때까지 오랜 시간이 걸릴 수 있습니다.즉, UI가 차단되거나 애플리케이션에서 I/O가 유휴 상태가 될 수 있습니다.
단, 적어도 Node.js의 process.nextTick 함수(마이크로태스크를 큐잉)에 관해서는 프로세스.maxTickDepth에 의한 블록에 대한 보호 기능이 내장되어 있습니다.이 값은 기본 1000으로 설정되어 있으며, 이 제한에 도달하면 마이크로태스크의 추가 처리가 중단되므로 다음 매크로태스크를 처리할 수 있습니다).
그럼 어떤 용도로 사용합니까?
기본적으로 동기식으로 작업을 수행해야 할 경우(즉, 가장 가까운 미래에 이(마이크로) 작업을 수행해야 할 경우) 마이크로 태스크를 사용합니다.그렇지 않으면 마크로타스크를 사용하세요.
예
macrotasks: set Timeout, setInterval, setImediate, requestAnimationFrame, I/O, UI 렌더링
마이크로태스크: process.nextTick, Promits, queueMicrotask, MutationObserver
사양의 기본 개념:
- 이벤트 루프에는 하나 이상의 태스크큐가 있습니다(태스크큐는 매크로태스크큐입니다).
- 각 이벤트 루프에는 마이크로태스킹큐가 있어요
- 작업 대기열 = macrotask 대기열!=
- 작업은 매크로태스크 큐 또는 마이크로태스크 큐로 푸시될 수 있습니다.
- 작업이 큐(마이크로/마이크로)에 푸시되면, 우리는 준비 작업이 끝나서 지금 작업을 실행할 수 있다는 것을 의미합니다.
이벤트 루프 프로세스 모델은 다음과 같습니다.
- 태스크 큐에서 가장 오래된 태스크(태스크 A)를 선택합니다.
- 태스크 A가 null인 경우(태스크 큐가 비어 있는 경우) 스텝6으로 점프합니다.
- "현재 실행 중인 작업"을 "작업 A"로 설정합니다.
- "태스크 A"를 실행합니다(콜백 함수를 실행합니다).
- "현재 실행 중인 작업"을 null로 설정하고 "작업 A"를 제거합니다.
- 이이마태태큐큐큐큐큐큐큐
- (a) 마이크로태스크 큐에서 가장 오래된 태스크(태스크 x)를 선택합니다.
- (b). 태스크x가 늘(마이크로태스크 큐가 비어 있음)인 경우 스텝(g)으로 넘어갑니다.
- (c) "current running task"를 "task x"로 설정합니다.
- (d) "task x"를 실행합니다.
- (e) "current running task"를 null로 설정하고 "task x"를 삭제합니다.
- (f) 마이크로태스크 큐에서 다음으로 오래된 태스크를 선택하고 스텝(b)으로 넘어갑니다.
- (g) 마이크로태스킹 큐를 삭제한다.
- 스텝 1로 넘어갑니다.
단순화된 프로세스 모델은 다음과 같습니다.
- 매크로태스크 큐에서 가장 오래된 태스크를 실행한 후 제거합니다.
- microtask 큐에서 사용 가능한 모든 태스크를 실행한 후 제거합니다.
- 다음 라운드: Macrotask 큐에서의 다음 작업 실행(스텝 2)
기억해야 할 사항:
- 태스크(매크로태스크 큐)가 실행 중일 때 새 이벤트가 등록될 수 있습니다.따라서 새로운 작업이 생성될 수 있습니다.을 사용하다
- A.then()을 약속하다
- promise A가 해결/거부되었습니다.이 작업은 이벤트루프의 현재 라운드에서 마이크로태스크 큐에 푸시됩니다.
- promise A가 보류 중: 향후 이벤트 루프 라운드에서 작업이 마이크로태스크 큐에 푸시됩니다(다음 라운드가 될 수 있음).
- setTimeout(callback,n)의 콜백은 태스크이며, n이 0인 경우에도 매크로태스크 큐에 푸시됩니다.
- A.then()을 약속하다
- macrotask 큐의 태스크는 이벤트 루프의 다음 라운드를 기다려야 하는 반면 마이크로태스크 큐의 태스크는 현재 라운드에서 실행됩니다.
- "click", "scroll", "ajax", "setTimeout..."의 콜백은 태스크이지만 스크립트 태그의 js 코드 전체도 태스크(매크로태스크)라는 것을 기억해야 합니다.
이벤트 루프는 스택에서 분리하여 논의할 수 없다고 생각합니다.
JS에는 3개의 "스택"이 있습니다.
- 모든 동기 콜의 표준 스택(한 함수가 다른 함수를 호출하는 등)
- priority가 높은 모든 비동기 조작(process.nextTick, Promits, Object.observe, MutationObserver)의 마이크로태스크 큐(또는 작업큐 또는 마이크로태스크 스택)
- priority가 낮은 모든 비동기 작업(setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI 렌더링)을 위한 macrotask 큐(또는 이벤트큐, 태스크큐, 매크로태스크 큐)
|=======|
| macro |
| [...] |
| |
|=======|
| micro |
| [...] |
| |
|=======|
| stack |
| [...] |
| |
|=======|
이벤트 루프는 다음과 같이 동작합니다.
- 스택에서 아래부터 위까지 모든 것을 실행합니다.스택이 비어 있는 경우에만 위의 큐에서 무슨 일이 일어나고 있는지 확인합니다.
- 마이크로스택을 체크하고 필요한 경우 스택의 도움을 받아 모든 것을 실행합니다.마이크로태스크 큐가 비거나 실행이 필요 없을 때까지 마이크로태스크를 하나씩 실행합니다.그 후에 매크로 스택을 체크합니다.
- 매크로 스택을 체크하고 필요한 경우 스택의 도움을 받아 모든 것을 실행합니다.
스택이 비어 있지 않으면 마이크로 스택은 건드리지 않습니다.마이크로 스택이 비어 있지 않거나 실행할 필요가 없는 경우 매크로 스택은 변경되지 않습니다.
요약: 마이크로태스크 큐는 매크로태스크 큐와 거의 동일하지만 이러한 태스크(process.nextTick, Promise, Object.observe, MutationObserver)는 매크로태스크보다 우선순위가 높습니다.
Micro는 매크로와 비슷하지만 우선순위가 더 높습니다.
여기에는 모든 것을 이해하기 위한 "최종" 코드가 있습니다.
console.log('stack [1]');
setTimeout(() => console.log("macro [2]"), 0);
setTimeout(() => console.log("macro [3]"), 1);
const p = Promise.resolve();
for(let i = 0; i < 3; i++) p.then(() => {
setTimeout(() => {
console.log('stack [4]')
setTimeout(() => console.log("macro [5]"), 0);
p.then(() => console.log('micro [6]'));
}, 0);
console.log("stack [7]");
});
console.log("macro [8]");
/* Result:
stack [1]
macro [8]
stack [7], stack [7], stack [7]
macro [2]
macro [3]
stack [4]
micro [6]
stack [4]
micro [6]
stack [4]
micro [6]
macro [5], macro [5], macro [5]
--------------------
but in node in versions < 11 (older versions) you will get something different
stack [1]
macro [8]
stack [7], stack [7], stack [7]
macro [2]
macro [3]
stack [4], stack [4], stack [4]
micro [6], micro [6], micro [6]
macro [5], macro [5], macro [5]
more info: https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3
*/
매크로 태스크에는 키보드이벤트, 마우스이벤트, 타이머이벤트, 네트워크이벤트, HTML 해석, Urletc 변경이 포함됩니다.매크로 태스크는 몇 가지 개별적이고 독립적인 작업을 나타냅니다.
마이크로태스크는 어플리케이션 상태를 갱신하는 작은 태스크이며 브라우저가 UI 재렌더링 등의 다른 할당을 계속하기 전에 실행해야 합니다.마이크로태스킹에는 약속 콜백 및 DOM 변환 변경이 포함됩니다.마이크로태스크를 사용하면 UI가 다시 렌더링되기 전에 특정 액션을 실행할 수 있기 때문에 애플리케이션 상태가 일관되지 않을 수 있는 불필요한 UI 렌더링을 피할 수 있습니다.
매크로 태스크와 마이크로태스크를 분리하면 이벤트루프가 퍼포먼스에 민감한 태스크에 우선순위를 부여하는 등 태스크 유형에 우선순위를 부여할 수 있습니다.
단일 루프 반복에서는 최대 1개의 매크로 태스크가 처리되며(다른 작업은 큐에 대기 상태로 남습니다), 모든 마이크로 태스크가 처리됩니다.
두 작업 큐는 모두 이벤트루프 외부에 배치되어 일치 큐에 작업을 추가하는 액션이 이벤트루프 밖에서 발생함을 나타냅니다.그렇지 않으면 JavaScript 코드 실행 중에 발생하는 모든 이벤트는 무시됩니다.작업 검출 및 추가 작업은 이벤트 루프와는 별도로 수행됩니다.
두 유형의 태스크가 한 번에 하나씩 실행됩니다.작업이 실행되기 시작하면 작업이 완료될 때까지 실행됩니다.브라우저만 작업 실행을 중지할 수 있습니다(예: 작업이 너무 많은 시간 또는 메모리를 사용하는 경우).
모든 마이크로태스크는 렌더링 전에 응용 프로그램 상태를 업데이트하는 것이 목표이므로 다음 렌더링 전에 실행해야 합니다.
브라우저는 보통 초당 60회 페이지를 렌더링하려고 합니다.애니메이션이 부드럽게 표시되는 속도는 초당 60프레임으로 인정됩니다.애플리케이션을 부드럽게 실행하려면 단일 태스크와 그 태스크에 의해 생성된 모든 마이크로태스크가 16밀리초 이내에 완료되는 것이 이상적입니다.태스크가 몇 초 이상 실행되는 경우 브라우저에 "응답하지 않는 스크립트" 메시지가 표시됩니다.
JavaScript는 고급 단일 스레드 언어이며 인터프리터 언어입니다.즉, JS 코드를 기계 코드로 변환하는 인터프리터가 필요합니다.인터프리터는 엔진을 의미합니다.크롬용 V8 엔진과 사파리용 웹킷.모든 엔진에는 메모리, 콜스택, 이벤트루프, 타이머, Web API, 이벤트 등이 포함됩니다.
이벤트 루프: 마이크로태스크 및 매크로태스크
이벤트 루프 개념은 매우 간단합니다.끝없는 루프가 있습니다.JavaScript 엔진은 작업을 기다리고 실행한 후 sleep 상태로 이행하며 더 많은 작업을 기다립니다.
작업이 설정되고 엔진에서 처리되며 더 많은 작업이 대기됩니다(절전 상태로 CPU가 거의 0에 가까운 상태).엔진이 비지 상태일 때 작업이 발생하여 대기열에 들어갈 수 있습니다.태스크는 이른바 "매크로태스크 큐"를 형성합니다.
마이크로태스크는 우리의 코드에서만 나옵니다.보통 약속에 의해 생성됩니다.그러면/catch/finally 핸들러의 실행은 마이크로태스크가 됩니다.마이크로태스크는 약속 처리의 또 다른 형태이기 때문에 대기라는 '덮개 아래'에서도 사용됩니다.모든 매크로태스크 직후 엔진은 다른 매크로태스크나 렌더링 또는 기타 작업을 실행하기 전에 마이크로태스크 큐에서 모든 작업을 수행합니다.
언급URL : https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context
'source' 카테고리의 다른 글
| jQuery를 사용하여 체크박스에 대해 "체크" 설정 (0) | 2023.01.15 |
|---|---|
| Mysql은 sudo와 함께 작동하지만 그렇지 않습니다.(ubuntu 16.04, mysql 5.7.12-0ubuntu1).1) (0) | 2023.01.15 |
| Vee가 v3 ValidationObserver가 v-for를 사용하여 추가된 동적 유효성 검사 제공자와 함께 작동하지 않음을 확인함 (0) | 2023.01.15 |
| 컬이 활성화 또는 비활성화되었는지 확인하는 방법 (0) | 2023.01.15 |
| 각도에서의 (변경) 대 (ngModelChange) (0) | 2023.01.15 |
