【前端面试】V8事件轮询

在前端面试中,面试官可能会问你V8的引擎机制,给你这样的一道题目如下:

js 复制代码
console.log(1);

setTimeout(() => { 
    console.log(2);
});
new Promise(reslove => {  
    console.log(3);  
    reslove();
}).then(() => {  
    console.log(4);
});

console.log(5);

面试官会让你给出题目中输出的顺序 以及执行原理

直接在浏览器运行我们可以知道输出的顺序是1、3、5、4、2 ,那这过程中到底为什么会这样输出呢?要了解这个打印顺序的原理,我们必须弄清楚V8的事件轮询机制。下面是一张原理图:

里面涉及到两个概念,一个是宏任务MacroTask,一个是微任务MicroTask。其中MacroTask所存放的任务队列有setTimeout,setinterval 。MicroTask里面所存放的队列有Promise,.then,还有process,.nextTick等等。

它轮询具体的方式是,我们这里假定一个流程,如下图:

从开始执行 ,代码优先执行同步的script片段 ,然后我们就一直把同步的执行完。执行完同步之后的我们一旦遇到有异步的代码,我们就开始进入任务类型的判断,如果判断应该存放于MacroTask的,我们就放到宏任务队列里,如果需要放到MicroTask,我们就存放到微任务队列里。

等到所有的同步代码 执行完毕之后,我们优先从微任务里面去把任务拉取出来执行,其次才是从宏任务队列里面拉任务出来执行,然后如此递归循环,直到把所有代码片段执行完毕。

分析:

我们再来回顾看一下上面题目里面的代码:

1.我们首先第一段console.log(1),那我们直接打印1。

2.然后再到setTimeout里面有一个console.log(2),那我们就把这个console.log(2)放到MacroTask队列。

3.然后进而我们看到new Promise,它是构造函数,那直接打印3,再到.then里面console.log(4),我们就放到MicroTask队列里面,也是微任务队列。

4.最后就是console.log(5),直接打印5。

总结:

所以经历过第一遍分析之后,我们打印了1、3、5,等所有代码执行完毕之后,我们优先从微任务里面把代码片段抽取出来,那就从console.log(4)提取出来并执行,那就打印4,最后从宏任务队列里面拿出console.log(2)出来执行,所以打印2。这样下来整体的顺序就会打印成1、3、5、4、2

相关推荐
Csvn11 分钟前
组合式 API(Composition API)
前端
火柴就是我1 小时前
Android 打包报错 25.0.3
android·前端
BD_Marathon1 小时前
消息对象中字段的说明
java·前端·python
八荒启·交互动画1 小时前
Web特效025—用 Canvas 2D 做Web特效的定义与边界:这支画笔能做到哪一步
前端·webgl·网页特效·八荒启-交互动画·八荒启
Ai-_Man1 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
excel2 小时前
Nuxt 中使用 useHead 优化 SEO 与 GEO
前端
IT_陈寒3 小时前
SpringBoot启动慢得像蜗牛?原来是这个配置在捣鬼
前端·人工智能·后端
计算机魔术师3 小时前
Muse Spark跑赢Gemini,但真正的底牌是这种设计
前端
PYB33 小时前
【Web·JS·基础】函数的使用和展运算符...objs
前端·javascript
指针向南3 小时前
Chrome读不了HEIC怎么办:原生解码和WASM两条路
前端·图像处理·人工智能·chrome·计算机视觉·wasm