首页IT科技js事件循环机制的运用(JS事件循环机制(面试快速解题技巧))

js事件循环机制的运用(JS事件循环机制(面试快速解题技巧))

时间2025-09-16 19:55:21分类IT科技浏览6656
导读:事件循环机制 同步与异步...

事件循环机制

同步与异步

我们先思考两个问题                ,如下:

为什么会存在同步和异步的概念?

我们的JavaScript是单线程的                         ,也就是我们的工作流水线的只有一条                 。如果我们的任务全放在流水线上         ,其中一个任务出现问题就会阻塞后面的任务            ,导致我们的工作流水线卡住                         。因此为了更加高效合理利用这条流水线                        ,在JavaScript中出现了同步与异步的概念        。

同步与异步任务如何在一条流水线上工作?

同样是一条流水线            。我们的有不同的产品             ,有的产品能瞬间完成        ,有的产品需要耗费大量时间才能完成                         。那么我们给这堆产品分为两类                        ,能瞬间完成的产品先放入流水线前面                 ,而需要耗费大量时间的产品则放在流水线后面            。将所有的产品按顺序从流水线上执行        。即使后面有部分产品制作很慢    ,但我们流水线前面的大部分产品都能顺利完成                         。也就是说                        ,我们能够及时交付大部分的产品                     ,让老板基本满意就足够了                。后面的产品我们再慢慢做也不迟    。

同步

同步任务:我们的任务不会造成流水线阻塞,瞬间就能完成                         。那我们直接把这些任务定义为同步任务                    。

同步事件:new Promise()                、async关键字                         、console对象方法

异步

异步任务:我们的任务可能会造成流水线阻塞                    ,需要时间才能完成。那我们直接把这些任务定义为异步任务                     。

异步事件:我们先不介绍异步事件                         ,因为异步事件又分为微任务与宏任务                        。我们下面再介绍    。

微任务与宏任务(异步事件)

微任务事件:Promise.then()         、await 后面的语句            、queueMiscrotask                        、MutationObserver             、process.nextTick( node.js环境 )[ 微任务中最先执行 ]

宏任务事件:setTimout() 和 setInterval()        、<script>脚本                        、I/O                 、UI交互事件    、setImmediate( node.js环境 )[ 宏任务中最后执行 ]

注意:异步事件分为微任务和宏任务    ,其中微任务优先于宏任务执行                 。

任务执行顺序

执行栈:同步代码会首先归类到此处待执行                         。按照代码的书写顺序(上到下)入栈        。

微任务队列:异步中的微任务代码归类到此处            。按照代码的书写顺序(上到下)入队                         。当执行栈为空时                ,微任务会出队进入执行栈            。

宏任务队列:异步中的宏任务代码归类到此处        。按照代码的书写顺序(上到下)入队                         。当微任务队列为空时                         ,宏任务会出队进入执行栈                。

我们采用验证法做几道题

第一道如下

console.log(1) setTimeout(() => { console.log(2) setTimeout(() => { console.log(3) }, 1000) }, 1000) new Promise((resolve, reject) => { console.log(4) resolve(5) // 之后会调用 then 方法 console.log(6) }).then((resolve, reject) => { console.log(resolve) }) function add(a, b) { return a + b } async function foo() { console.log(7) let num = await add(4, 4) console.log(9) return num } foo().then((num) => { console.log(num) }) console.log(10) // 1 4 6 7 10 5 9 8 2 3

以上代码没有出现宏任务嵌套微任务         ,微任务嵌套宏任务的情况    。那么我们可以按编号(对应的输出语句)直接对执行栈                        、微任务和宏任务分类如下:

第一次分析执行栈(同步任务):1 4 6 7 10

第二次分析微任务:5 9 8

第三次分析宏任务:2 3

然后我们按执行顺序将答案组合在一起                         。最终答案:1 4 6 7 10 5 9 8 2 3                    。

注意:以上分析方法只能应对异步函数无嵌套的情况。

接下来我们增加难度            ,宏任务嵌套微任务                        ,微任务嵌套宏任务                     。第二题如下

console.log(1) setTimeout(() => { console.log(2) new Promise((resolve, reject) => { console.log(3) resolve(4) }).then((resolve, reject) => { console.log(resolve) }) console.log(5) }, 1000) console.log(6) new Promise((resolve, reject) => { console.log(7) resolve(8) setTimeout(() => { console.log(9) }, 1000) }).then((resolve, reject) => { console.log(resolve) }) console.log(10) // 1 6 7 10 8 2 3 5 4 9

以上代码出现了宏任务嵌套微任务             ,微任务嵌套宏任务的情况                        。

提示:外部(全局作用域)的代码可以按任务执行顺序分析        ,异步函数内部其实也可以按照我们的任务执行顺序分析    。其分析过程是一样的                 。

最终答案:1 6 7 10 8 2 3 5 4 9                         。还有很多特例                        ,可自行编写异步函数测试        。总结方法

最终总结

分析方法:先对代码进行事件分类                 ,然后分别放入对应类型的三个地方(执行栈                     、微任务队列和宏任务队列)再按照我们的执行顺序    ,发生异步函数嵌套情况时                        ,也可以对其内部应用这套规则解决            。

任务执行顺序如下

同步(new Promise()、async关键字                    、console对象方法) process.nextTick(node.js环境) 微任务(异步)(Promise().then()                         、await 后面的语句) 宏任务(异步)(定时器函数    、<script>脚本                、I/O                         、UI交互事件) setImmediate(node.js环境)(当前事件循环结束后执行)

参考

【前端八股文】事件循环-宏任务和微任务

声明:本站所有文章                     ,如无特殊说明或标注,均为本站原创发布                         。任何个人或组织                    ,在未征得本站同意时                         ,禁止复制         、盗用            、采集                        、发布本站内容到任何网站             、书籍等各类媒体平台            。如若本站内容侵犯了原著者的合法权益    ,可联系我们进行处理        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
python列表删除元素所有方法(python中remove()方法如何使用删除后的值?) 域名备案视频教程(域名备案全流程解析及购买技巧)