>  기사  >  웹 프론트엔드  >  자바스크립트 이벤트 루프의 강제 정렬

자바스크립트 이벤트 루프의 강제 정렬

巴扎黑
巴扎黑원래의
2017-07-19 15:42:491515검색

js 단일 스레드

js는 단일 스레드이므로 프로세스와 스레드에 대한 자세한 설명을 보려면 포털을 클릭하면 됩니다. 기본적으로 웹 작업자가 생성한 스레드는 메인 스레드에 의해 제어되며 계산만 수행할 수 있습니다.

js 동기화, 비동기

동기 실행: 즉, js 메인 스레드는 작업을 순서대로 실행하고 대기합니다. webAPI/ajax 및 기타 코드를 실행할 때의 응답 다음 코드는 실행될 수 없습니다. 즉, 다음 작업은 이전 작업이 완료될 때까지 기다려야 합니다.

비동기 실행: js는 단일 스레드이며 비동기 기능이 없지만, 브라우저는 js가 실행될 때 webAPI(예: setTimeout/ajax 등)를 발견하고 즉시 값을 반환하므로 메인 스레드를 차단하지 않으며 완료 후 실제 비동기가 실행됩니다. 콜백 함수는 js 메인 스레드의 메시지 큐에 푸시되고 메인 스레드가 호출할 때까지 기다립니다.

이벤트 루프 메커니즘 [이벤트 루프]

js가 실행될 때 메인 스레드에는 실행 스택이 있습니다. stack](스택) 및 메시지 큐(작업 큐 또는 이벤트 큐라고도 함)(이벤트 큐); js가 함수를 만나면 함수가 실행된 후 스택에 푸시되고 팝업됩니다. 실행 스택을 호출하고 실행합니다. webAPI를 만나면 비동기적으로 실행됩니다. 실행 스택에 작업이 없으면 기본 스레드가 메시지를 쿼리하고, 쿼리가 성공하면 쿼리된 작업이 실행됩니다. 실행 스택이 빌 때까지 실행을 위해 스택에 푸시되고 메시지 큐가 다시 쿼리됩니다. 이는 브라우저에 의해 비동기 실행이 완료되기 때문에 유명한 이벤트 루프인 [이벤트 루프]를 형성합니다. js 스레드가 차단되었을 때 작동하는 DOM 이벤트가 스레드가 복원된 후 순차적으로 실행되는 이유를 이해합니다. [js 메인 스레드의 작업 대기열이 브라우저에 의해 푸시되고 js 스레드가 차단됩니다!== 브라우저 스레드는 즉, 메인 스레드 차단은 작업을 작업 대기열로 푸시하는 것을 방지하지 않습니다.]

또 다른 코드 조각:

      // 主线程执行fn1任务  1function fn1(){ 
                console.log("任务1执行")// 遇到webAPI立即返回 这里是undefined值 并交给浏览器对应线程处理 2  // 浏览器收到后 0 毫秒将回调函数推入消息列队; 异步执行setTimeout(function(){// 查询到一个回调任务 入栈执行    5console.log("回调1执行")// 遇到webAPI立即返回 这里是undefined值 并交给浏览器对应线程处理  6  // 浏览器收到后 500   毫秒将回调函数推入消息列队; 异步执行setTimeout(function(){// 查询到一个回调任务 入栈执行    7console.log("回调2执行")
                    },500)
                },0)
            }// 主线程执行fn2任务 3function fn2(){console.log("任务2执行")}// 执行栈没有可执行任务 开始查询消息列队 4

Macrotasks 및 Microtasks

메시지 대기열이 나누어집니다. Macrotasks[Task Queue] 및 Microtasks[ Microtasks Queue ]의 두 가지 유형으로

  • macrotasks: setTimeout, setInterval, setImmediate, I/O, UI 렌더링setTimeoutsetIntervalsetImmediate, I/O, UI rendering

  • microtasksprocess.nextTickPromisesObject.MutationObserver

microtasks: process.nextTick, Promise, Object.MutationObserver

두 가지 중 어느 것을 먼저 실행해야 하는지 궁금합니다. Promise/A+ 사양은 다음과 같습니다.
여기서 "플랫폼 코드"는 엔진, 환경 및 Promise 구현 코드를 의미합니다. 실제로 이 요구 사항은 이벤트 루프가 호출된 후 onFulfilled 및 onRejected가 비동기적으로 실행되도록 보장합니다. 이것은 setTimeout 또는 setImmediate와 같은 "매크로 작업" 메커니즘 또는 MutationObserver 또는 process.nextTick과 같은 "마이크로 작업" 메커니즘을 사용하여 구현할 수 있습니다. 플랫폼 코드로 간주되면 핸들러가 호출되는 작업 일정 대기열 또는 "트램폴린"이 포함될 수 있습니다. 실제로 메시지 대기열을 쿼리할 때 실행 프로세스도 이해하기 쉽습니다. 이전 쿼리를 기반으로 microtasks는 모든 작업을 실행한 후 macrotasks를 쿼리합니다. macrotasks에 microtasks 작업이 있으면 다음 쿼리가 먼저 실행됩니다. 이것은 쿼리됩니다macrotasks입니다. 메시지가 대기열에 들어갈 때까지 반복됩니다. [two Queue] 작업 없음;
위 코드를 확인하세요. [약속 기능은 es6이므로 노드 환경을 사용하세요]
console.log(170 Promise(89100 Promise(34562);
// 1 2 3 4 5 6 7 8 9 10
🎜

위 코드의 실행 과정:

js는 콘솔 1을 실행합니다. setTimeout이 발생하면 비동기 실행으로 변경되고, 다시 setTimeout이 발생하면 다시 비동기적으로 실행됩니다. 그런 다음 실행이 Promise를 만나면 실행됩니다. microtasks 유형 작업 큐에 푸시된 후 콘솔 2가 실행됩니다. 이 시점에서 실행 스택은 비어 있습니다. 메시지 큐를 쿼리하려면 먼저 microtasks를 쿼리하고 실행 가능한 작업이 있는지 찾으세요. 실행을 위해 스택에 푸시되고 그에 따라 3 4 5 6이 인쇄됩니다. [마이크로 태스크가 비어 있지 않은 한 비어 있을 때까지 실행됩니다] 메시지 대기열을 다시 쿼리합니다. 이때 microtasks 대기열에는 실행할 작업이 없습니다. 그런 다음 macrotasks 대기열을 쿼리하고 실행을 위해 대기 중인 setTimeout 콜백을 찾은 다음 이를 꺼내어 대기열을 다시 쿼리합니다. . 이때 microtasks 대기열에는 아직 작업이 없습니다. 그런 다음 macrotasks 대기열을 쿼리하고 실행을 기다리는 setTimeou 콜백을 찾으면 약속이 microtasks 대기열로 푸시되고 팝업되는 것을 발견합니다. 스택이고 실행 스택은 다시 비어 있습니다. 메시지 대기열을 쿼리하고 microtasks에 실행 가능한 작업이 있는지 확인합니다. 이 시점에서 기본 스레드는 대기 상태입니다.

위 내용은 자바스크립트 이벤트 루프의 강제 정렬의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.