浏览器事件循环探讨 event loop
创始人
2024-03-26 10:14:47
0

有以下demo,最终控制台会输入的内容是啥

 setTimeout(()=>{console.log("timer1")Promise.resolve(1).then(()=>{console.log("promise1")})console.log("timer 1normal")})setTimeout(()=>{console.log("timer2")})console.log("primary")

  • 1,第一个是primary,这个没有疑问,住流程的代码先执行嘛
  • 2,然后是timer1
  • 3,再然后是timer 1normal,
  • 4,,接着是promise1
  • 5,timer2

为什么1比2快呢?

因为1是主流程代码,2是宏任务里面的代码啊🤔

那为什么3比4快呢?

因为3是主流程代码啊,4是微任务里面的代码🤔

好像这样开始有点迷茫了~~,3和4不是都在宏任务里面的么。

宏任务队列和微任务队列

得有【宏任务队列和微任务队列】这些概念才能更好理解代码

假设浏览器底层有以下代码

var macroTask = [];//宏任务var microTask = [];//微任务var timer;//事件轮训的定时器window.setTimeoutx = function (cb) {macroTask.push(cb);}//模拟Promise.resolve(1).thenwindow.micpush = function (cb) {microTask.push(cb);}var eventLoop = function () {clearTimeout(timer);//这块代码是为了演示作用,正常环境不会有==========【if (macroTask.length || microTask.length) {console.warn("macroTask", macroTask, 'microTask', microTask)}else {console.warn("宏任务和微任务队列为空")}//这块代码是为了演示作用,正常环境不会有==========】function callListFn(arr, ismac) {let curr = arr.shift();curr();//再检测下是否有微任务//这里其实这样写不啊合适,只是暂时配合模拟效果if (ismac) {//微任务while (microTask.length) {callListFn(microTask);}}}//微任务while (microTask.length) {callListFn(microTask);}//宏任务while (macroTask.length) {callListFn(macroTask, true);}//模拟事件循环,定时轮询timer = setTimeout(() => {eventLoop();}, 1000)};//事件循环//开启事件循环eventLoop();

我们开发时候所写的代码

  • setTimeoutx模拟window.setTimeout
  • micpush 模拟Promise.resolve(1).then 这个api

      

 setTimeoutx(()=>{console.log("timer1")//模拟Promise.resolve(1).then 这个apimicpush(()=>{console.log("promise1")})console.log("timer 1normal")})setTimeoutx(()=>{console.log("timer2")})console.log("primary")console.warn("macroTask",macroTask,'microTask',microTask)

你会发现浏览器console.log打印的内容和我们第一段代码一模一样

本质

        setTimeout,Promise.resolve(1).then他们都是往底层的任务队列里面添加个函数元素而已,并非任务本身,函数类型的参数才是要被执行的任务,只是执行的权限交给了事件轮询。而事件轮询是定期的遍历执行微任务队列和宏任务队列里面的元素。只是微任务的执行优先于宏任务。

步骤解说

注意序号❕

//1setTimeout(()=>{//4console.log("timer1")// 5Promise.resolve(1).then(()=>{//8 console.log("promise1")})//6Promise.resolve(1).then(()=>{//9 console.log("promise1")})//7console.log("timer 1normal")})//2.setTimeout(()=>{//10  console.log("timer2")})// 3console.log("primary")

针对上面不同步骤的微任务队列和 任务队列

//1

macroTask = [fn1];//宏任务

microTask = [];//微任务

//2

macroTask = [fn1,fn2];//宏任务

microTask = [];//微任务

//3

macroTask = [fn1,fn2];//宏任务

microTask = [];//微任务

执行【打印"primary”】

【开始事件轮询1】

//4

执行【打印"timer1”】

macroTask = [fn2];//宏任务,正在执行fn1宏任务,所以要把他移除处队列

microTask = [];//微任务

//5

执行【打印"timer1”】—已经执行了,

macroTask = [fn2];//宏任务,正在执行fn1宏任务,所以要把他移除处队列

microTask = [fn3];//微任务,Promise.resolve(1).then 给微任务队列塞入个元素

//6

执行【打印"timer1”】—已经执行了,

macroTask = [fn2];//宏任务,正在执行fn1宏任务,所以要把他移除处队列

microTask = [fn3,fn4];//微任务,Promise.resolve(1).then 给微任务队列塞入个元素

//7

执行【打印"timer 1normal”】

macroTask = [fn2];//宏任务,没有执行下一个事件轮训所以【本轮事件轮训】宏任务还有一个元素

microTask = [fn3,fn4];//微任务,因为还没有执行下一个事件轮训所以【本轮事件轮训】微任务还有2个元素

//开启第二轮事件轮询,8,9,10,微任务【8,9】优先

最终

microTask = [];//微任务

macroTask = [];//宏任务

以上的代码可以在线测试​​​​​​​

相关内容

热门资讯

六月二十七日望湖楼醉书 这首诗... 六月二十七日望湖楼醉书 这首诗的写作结构是怎样的?雨前:黑云到入船。雨停:第三句。雨后:最后一句
如果我带着醉意出生,或许我会忘... 如果我带着醉意出生,或许我会忘掉所有的哀伤,这是哪本书上的句子《八百万种死法》,最近电视剧无懈可击之...
优美动人怎么造句孑 优美动人怎么造句孑她的舞姿优美动人,真是让人难以忘怀!
在科学上没有平坦的大道,只有不... 在科学上没有平坦的大道,只有不畏艰险沿着陡峭山路攀登的人,才有希望达到光辉的顶点。这句话的意思。这句...
有什么好看的网王小说?要完结的 有什么好看的网王小说?要完结的四叶三叶草,我的幸福《网王守望幸福《网王——今生无忧》(《夏之纪年》《...
郭达换大米剧本谁写的 郭达换大米剧本谁写的换大米的作者是 郭达和蔡明
园林绿化公司怎么起名 园林绿化公司怎么起名我们是做园林绿化设计、施工管理的自然世界园林绿化公司,新鲜空气园林绿化公司,超时...
命运石之门,谁发信对主人公说你... 命运石之门,谁发信对主人公说你知道的太多了FB指示萌郁发送的(官方资料设定集里写了)FB即是楼下的显...
有关超市开业播放的音乐 有关超市开业播放的音乐请各位关注本问题的大侠们,帮我找一下超市、商场开业时用到的喜庆音乐!谢谢,有追...
现代人物人物苦学成才的故事 现代人物人物苦学成才的故事现代人物人物苦学成才的故事 张恨水先生是我国著名的现代作家。17岁时,他...
是惊的成语,以惊字结尾的成语,... 是惊的成语,以惊字结尾的成语,惊字在后面的成语 第四个字是惊的成语详细〔 胆颤心惊 〕颤:发抖。形...
判断一个女人对你“欲擒故纵”,... 判断一个女人对你“欲擒故纵”,还是“压根没戏”,关键看哪几点?首先知竖,对方给你回消息的语气。如历芹...
自己写的儿童诗 自己写的儿童诗有什么可以帮你的追问:我要自己写的儿童诗,谢谢了!追答:主要是我都不知道有什么要求啊追...
地下城堡2聚火之心有用吗 地下城堡2聚火之心有用吗有用。《地下城堡2:黑暗觉醒》是一款模拟经营与地牢探险游戏高贺轿。游戏中聚火...
在学校如何和老师斗智斗勇 在学校如何和老师斗智斗勇 老师说上课是对牛弹琴时,作为学生的我们应该感到高兴,因为老师说的是事实啊...
神级龙卫男主和谁在一起 神级龙卫男主和谁在一起你好。神级龙卫男主沈浪跟女主白倾雨,苏若雪,柳潇潇最终走到一起了。让我们来看看...
开学以来作文520初中 开学以来作文520初中初一的感觉 似水流年,今天的我们已不再是在草地里玩过家家的小朋友;今天的我们已...
家有黄仙能养两只猫吗 家有黄仙能养两只猫吗可以养的,不犯冲突,猫捉老鼠是老鼠的天敌,养猫后家里的老鼠会少很多。
失忆后的人会不会有恐惧和绝望的... 失忆后的人会不会有恐惧和绝望的心理?我是指那种完全忘记了自己的一切的人。失忆...如果真的全部忘记,...
胡萝卜长期保存方法 胡萝卜长期保存方法胡萝卜放保鲜袋里放冰箱可以放很长时间。