JavaScript의 이벤트 루프 메커니즘에 대해 계속 이야기하겠습니다. JavaScript 이벤트 루프 메커니즘에 대한 첫 번째 강의는 아직 끝나지 않았습니다. JavaScript 이벤트 루프 메커니즘에 대해 계속해서 이야기해 보겠습니다.
지난 기사에서 JavaScript 이벤트 루프 메커니즘에 대한 일반적인 소개를 했지만 결국에는 코드 조각과 몇 가지 질문이 남았습니다. 먼저 이 코드부터 시작하겠습니다(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console.log(1); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3); })()이 코드에서 setTimeout과 Promise는 모두 작업 소스라고 하며, 서로 다른 작업 소스의 setTimeout의 콜백 함수는 setTimeout의 작업 대기열에 배치됩니다. Promise의 경우 콜백 함수는 전달된 실행자 함수가 아니라 Promise의 작업 대기열에 배치되는 비동기식으로 실행되는 then 메서드의 매개변수입니다. 즉, Promise의 첫 번째 매개변수는 Promise 작업 대기열에 포함되지 않고 현재 대기열에서 실행됩니다. setTimeout과 Promise의 작업 대기열을 매크로 작업(macro task)이라고 합니다. 물론 우리가 생각하는 것처럼 마이크로 작업(micro task)도 있습니다.
실행 프로세스 분석
다음 분석 아이디어는 이전에 동급생 Bo가 작성한 이벤트 루프 메커니즘에 대한 심층적인 핵심 및 자세한 설명에 따라 분석됩니다.
이전의 밤나무를 분석 대상으로 사용하여 이벤트 루프 메커니즘이 코드를 실행하는 방식을 분석합니다(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console.log(1); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3); })()아래 모든 그림의 setTimeout 태스크 팀과 최종 함수 호출 스택은 setTimeout 콜백 함수를 저장합니다. 전체 세트Timeout
timer.
1. 먼저 스크립트 태스크 소스가 먼저 실행되고 전역 컨텍스트가 스택에 푸시됩니다. 2. 스크립트 작업 소스 코드가 실행 중에 setTimeout을 만나면 매크로 작업으로 콜백 함수를 자체 대기열에 넣습니다. 3. 스크립트 작업 소스의 코드가 실행 중에 Promise 인스턴스를 발견합니다. Promiseconstructor의 첫 번째 매개변수는 현재 작업이 직접 실행될 때 대기열에 들어가지 않으므로 이때 1이 출력된다는 것입니다.
4. 5. 그런 다음 실행하면 코드가 then 메서드를 만나고 해당 콜백 함수가 마이크로 작업으로 스택에 푸시되고 Promise 작업 대기열에 들어갑니다. 6. 그러면 코드가 실행됩니다. 이때 console.log(3)이 발생하고 3이 출력됩니다.7.输出3之后第一个宏任务script的代码执行完毕,这时候开始开始执行所有在队列之中的micro-task。then的回调函数入栈执行完毕之后出栈,这时候输出5
8.这时候所有的micro-task执行完毕,第一轮循环结束。第二轮循环从setTimeout的任务队列开始,setTimeout的回调函数入栈执行完毕之后出栈,此时输出4。
总结
总的来说就是:
1、不同的任务会放进不同的任务队列之中。
2、先执行macro-task,等到函数调用栈清空之后再执行所有在队列之中的micro-task。
3、等到所有micro-task执行完之后再从macro-task中的一个任务队列开始执行,就这样一直循环。
4、当有多个macro-task(micro-task)队列时,事件循环的顺序是按上文macro-task(micro-task)的分类中书写的顺序执行的。
测试
说到这里,我们应该都明白了,下面是一个复杂的代码段(改自深入核心,详解事件循环机制),里面有混杂着的micro-task和macro-task,自己画图试试流程哇,然后再用node执行看看输出的顺序是否一致。
console.log('golb1'); setImmediate(function() { console.log('immediate1'); process.nextTick(function() { console.log('immediate1_nextTick'); }) new Promise(function(resolve) { console.log('immediate1_promise'); resolve(); }).then(function() { console.log('immediate1_then') }) }) setTimeout(function() { console.log('timeout1'); process.nextTick(function() { console.log('timeout1_nextTick'); }) new Promise(function(resolve) { console.log('timeout1_promise'); resolve(); }).then(function() { console.log('timeout1_then') }) setTimeout(function() { console.log('timeout1_timeout1'); process.nextTick(function() { console.log('timeout1_timeout1_nextTick'); }) setImmediate(function() { console.log('timeout1_setImmediate1'); }) }); }) new Promise(function(resolve) { console.log('glob1_promise'); resolve(); }).then(function() { console.log('glob1_then') }) process.nextTick(function() { console.log('glob1_nextTick'); })
讲到这里我们的细说JavaScript事件循环机制也就正式讲完了,看不懂了两篇结合起来看看,练练即可!
先看看我吧:
위 내용은 JavaScript 이벤트 루프 메커니즘에 대한 자세한 설명 - 강의 2의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!