事件循环、宏任务、微任务一网打尽(附超多经典面试题)
1.宏任务macrotask/Tasks:
(1)种类:
script主代码块、setTimeout 、setInterval 、nodejs的setImmediate 、MessageChannel(react的fiber用到)、postMessage、网络I/O、文件I/O、用户交互的回调等事件、UI渲染事件(DOM解析、布局计算、绘制)等等
(2)宏任务的问题 , 也即为什么要有微任务?
时间粒度比较大 , 执行的时间间隔是不能精确控制的 , 消息队列中就有可能被插入很多系统级的任务 , 对一些高实时性的需求就不太符合了;所有设计了微任务 , 通俗的讲微任务可以插队 , 本轮宏任务最后 , 插在下一轮宏任务之前 , 微任务队列的任务一次性全部执行完;
2.微任务包括microtask/jobs:
(1)种类:
- 浏览器端有3个1)new Promise.then 回调2)MutationObserver , 监控dom节点变化;MutationObserver使用“异步”+“微任务”的方式 , 替代旧版mutation event这个同步事件 , 异步解决同步操作的性能问题;微任务解决了实时性的问题;3)Object.observe , 已经废弃了 , 用Proxy对象替代;
- nodejs有2个 , process.nextTick、 new Promise.then 回调
(2)优先级如下:
nodejs中process.nextTick >new Promise.then(回调) > MutationObserver
(3)宏任务和微任务的关系
每个宏任务可以创建自己的一个微任务队列;
本文插图
3.一个宏任务微任务的例子 , 理解用户点击事件和JS模拟点击事件的区别
- 当我们使用 手动点击按钮时 , 浏览器的输出是listener1 -> promise resolved 1 -> listener2 -> promise resolved 2
- 当我们使用 JS触发点击行为时 , 浏览器的输出是listener1 -> listener2 -> promise resolved 1 -> promise resolved 2原因:
(1)人工点击
本文插图
- 从上图中我们可以看到 , 一次点击事件之后 , 浏览器会调用 Function Call 进入JS引擎 , 执行 listener1 , 输出 listener1 。
- 弹栈时发现JS调用栈为空 , 这时候就会执行 Microtasks 队列中的所有 Microtask , 输出 promise resolved1 。
接着浏览器调用 Function Call 进入JS引擎 , 执行 listener2 , 输出 listener2 。
弹栈时发现JS调用栈为空 , 这时候就会执行 Microtasks 队列中的所有Microtask , 输出 promise resolved2 。
(2)JS触发点击事件
本文插图
- 从上图中我们可以看到 , 浏览器运行JS代码时 , 调用了 button.click 这个函数
- 狐獴|\非洲精灵\狐獴,毒蝎、眼镜蛇都礼让7分!它有何威名?
- 世界卫生组织|宇宙有哪些高能事件,你知道吗?
- 美团|支付二维码管制,微信、支付宝躺枪,谁是最大赢家?
- 外星人绑架|贝蒂安德烈事件,美国最离奇的外星人绑架案,至今仍是谜?
- 荣耀|荣耀60系列爆料汇总:外观、性能、拍照、续航基本都确认了
- 创业|马云可能也没料到,“电商黑马”出现,拼多多、京东和淘宝难办了
- 百度|派财经 · 一周热闻:工信部因电信网络诈骗约谈阿里云、百度云;腾讯回应APP暂停更新
- 魅族|从3999降至2499,8+256GB、三星定制屏,魅族也有高性价比
- 纳米|用于长距离、超安全的量子通信的纳米天线
- 音箱|人类高质量监听书架音箱推荐,从劲浪、JBL到丹拿,九个品牌简评