事件循环、宏任务、微任务一网打尽(附超多经典面试题)( 三 )
1.机制如下:
浏览器的事件循环 , 是在渲染进程中的;执行一个宏任务 , 栈中没有就从事件队列中获取;执行过程中如果遇到微任务 , 就添加到微任务的队列中;当前这个宏任务执行完毕后 , 立即执行当前微任务队列的所有微任务;当前宏任务执行完毕 , GUI线程接管渲染;渲染完毕后 , JS线程继续接管 , 开始下一个宏任务;
简化就两步:执行一个宏任务 , 执行完它对于的所有微任务;
本文插图
2.浏览器渲染进程有三个异步队列
- 宏任务macrotask/Tasks
- 微任务Microtasks/Jobs
- Animation callbacks:requestAnimationFrame也属于异步执行的方法 , 但该方法既不属于宏任务 , 也不属于微任务 。
(1)宏任务队列 , 每次循环只执行一个 。 设置 2 个相同时间的 timeout , 两个并不会一起执行 , 依然是分批的 。 (2)微任务队列 , 每次循环会把队列全部执行完才继续 。 因此如果任务本身又新增 Microtasks , 也会一直执行下去 。 所以下面的例子才会产生阻塞 。
(3)Animation callbacks队列 , 每次循环执行队列里的全部任务 , 连续调用两句 requestAnimationFrame , 会在同一次事件循环执行;但是任务本身又新增 Animation callback 是放到下一个循环执行 , 不会阻塞;(4)例题:
1)test1会导致执行栈溢出 , 因为所有的代码都在同步执行栈中 , 最大栈深度25000 , 溢出;2)test2 , 可以正常运行 , 因为把任务移到了宏任务队列中 , 没有阻塞主渲染线程;3)test3可以运行 , 但是会造成页面卡顿 , 因为微任务队列自身创建微任务 , 会不停创建执行、创建执行 , 虽然不会爆栈 , 但是阻塞了主线程 , 页面卡顿严重;
3.promise相关的经典面试题
(1)promise.then要等到resolve之后加入当前宏任务后面的微任务中;
- 第一轮:宏任务1, 4;微任务:空
- 第二轮:宏任务2;微任务:3
- 第三轮:宏任务5 ,微任务:resolve了 , 把对应微任务加入~~7、8、9
- 第四轮:6结果依次输出:1 4 2 3 5 7 8 9 6
(2)promise.then 中 return Promise.resolve, 会产生类似两轮的微任务
4的地方产生两轮微任务 , 所以3、7这一轮完了要再等两轮 , 再8、9之后输出输出结果:1、5、2、6、3、7、8、9、4、10
具体V8的底层原理 , 可以看知乎这一个问题
一.nodejs中事件循环和浏览器的异同
1.底层不同
一个基于浏览器;一个基于libuv库;放一个nodejs的系统架构图
- 狐獴|\非洲精灵\狐獴,毒蝎、眼镜蛇都礼让7分!它有何威名?
- 世界卫生组织|宇宙有哪些高能事件,你知道吗?
- 美团|支付二维码管制,微信、支付宝躺枪,谁是最大赢家?
- 外星人绑架|贝蒂安德烈事件,美国最离奇的外星人绑架案,至今仍是谜?
- 荣耀|荣耀60系列爆料汇总:外观、性能、拍照、续航基本都确认了
- 创业|马云可能也没料到,“电商黑马”出现,拼多多、京东和淘宝难办了
- 百度|派财经 · 一周热闻:工信部因电信网络诈骗约谈阿里云、百度云;腾讯回应APP暂停更新
- 魅族|从3999降至2499,8+256GB、三星定制屏,魅族也有高性价比
- 纳米|用于长距离、超安全的量子通信的纳米天线
- 音箱|人类高质量监听书架音箱推荐,从劲浪、JBL到丹拿,九个品牌简评