分享:JS事件循环机制,宏任务和微任务
为什么会讲这个主题?
这要从一个bug讲起,10月26号,app端,我的考勤日历面板上的信息在ios上显示不全。效果见手机视频。
当时我们几个排查了2-3天都没找到原因,review代码各种改都不行。(此时打开代码看下,src/app/myAttendance/attendance.vue line298 line246)
最后通过setTimeout解决
前两天又遇到一个bug,先给大家看一下,http://jira.worktrans.cn/browse/XBUGXM-2998
部门统计-打卡明细-部门选择器数据加载(src/app/department/pages/detail.vue)
组件位置:src/common/components/dep-emp-select/index.vue
讲下如何修复的
这两个bug都是因为js代码执行时机不当导致的。
由此延伸的JS事件循环机制
参考:https://juejin.im/post/6844903638238756878
首先我们要知道:
- JavaScript是单线程的语言
- Event Loop是javascript的执行机制
javascript事件循环
任务分为两类:
- 同步任务
- 异步任务
先看一段代码:
宏任务:
setInterval()
setTimeout()
微任务:
new Promise()
在一个事件循环中,异步事件返回结果会被放到一个任务队列中。
在当前执行栈为空的时候,主线程会查看微任务队列是否有事件存在。如果不存在,那么再去宏任务队列
中取出一个事件并把对应的回调加入当前执行栈;如果存在,则会依次执行队列中事件对应的回调,知道微任务队列为空,然后去宏任务队列中取出最前面的一个事件,把对应的回调加入当前执行栈……如此反复循环。
同一次事件循环中,微任务永远在宏任务之前执行。
详细的事件循环顺序:
脚本-微任务-渲染
微任务会在执行任何其他事件,或渲染,或执行任何其他宏任务之前完成
事件循环的详细算法:
1. 从宏任务队列(例如script)中出队,并执行最早的任务
2. 执行所有微任务
当微任务队列非空时,出队并执行最早的微任务
3. 执行渲染
4. 如果宏任务队列为空,则休眠直到出现宏任务
5. 转到步骤1
安排一个新的宏任务
使用0延迟的setTimeout(f)
它可被用于将繁重的计算任务拆分成多个部分,以使浏览器能够对用户事件作出反应
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
2020-08-30 Angular中的可观察对象