让我来为您讲解Javascript运行机制之Event Loop的完整攻略。
什么是Event Loop
Event Loop(事件循环)是指在Javascript的运行期间,用于处理异步操作的一种机制。其中异步操作包括setTimeout、Promise、DOM事件等等。
当Javascript代码遇到异步操作的时候,会将其放入事件队列(Event Queue)中,等待执行。Event Loop则不断地监听主线程的调用栈和事件队列的状态,当调用栈为空时,才会将事件队列中的任务压入调用栈中执行。
过程分析
1.在主线程中,遇到一个宏任务(如同步代码、setTimeout等)时,它会立即进入调用栈中执行。
2.当遇到微任务(如Promise.then、process.nextTick等)时,它并不会立即进入调用栈中执行。而是被放到暂存区中,等主线程的调用栈为空时,再执行所有的微任务。
3.在执行宏任务、微任务中遇到其他宏任务或微任务时,同样按照上述的方式来处理。
4.不断重复执行上述步骤,直到事件队列中的所有任务都被处理完毕。
下面,我给出两个具体的示例说明:
示例一
console.log('1');
setTimeout(function() {
console.log('2')
}, 0);
console.log('3');
运行上述代码后,会在控制台上输出"1"、"3"、"2"。原因是setTimeout被放入了事件队列中,当主线程调用栈为空时,才会将其放入调用栈中执行。
示例二
console.log(1);
new Promise(function(resolve) {
console.log(2);
setTimeout(function() {
console.log(3);
}, 0);
resolve();
}).then(function() {
console.log(4);
});
console.log(5);
运行上述代码后,会在控制台上输出"1"、"2"、"5"、"4"、"3"。原因是:
1.执行"1"的打印,输出"1"。
2.创建Promise,并立即执行其内部的代码块,输出"2"。
3.将setTimeout所在的回调函数放入事件队列中,等待执行。
4.执行resolve,将Promise状态变成fulfilled,此时便触发了Promise中的.then方法注册的回调函数。
5.输出"4"。
6.当主线程调用栈为空时,开始执行微任务,将放在暂存区中的.then回调函数放入调用栈中执行。输出"3"。
结论
在Javascript的事件循环过程中,异步操作会被放到事件队列中。当主线程调用栈为空时,才会执行事件队列中等待执行的异步操作。其中,微任务的执行优先于宏任务,同一次事件循环中的微任务都会优先执行完毕,再执行宏任务。当一个宏任务执行结束后,下一个宏任务又需要等待上一个微任务全部执行完成后才能执行。而如果一个宏任务中又触发了新的异步操作,则新的异步操作将被挂起,等待主线程调用栈执行完毕后再被执行。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Javascript运行机制之Event Loop - Python技术站