JS 中的事件循环(Event Loop)和微任务与宏任务完全解析

互联架构唠唠嗑2024-04-11 18:39:30  72

介绍首先,地球人都知道JS是单线程的,所以JS同时只能执行一个任务,也就是只有一个调用栈,先执行同步任务,再执行异步任务。虽然HTML5允许JS脚本创建多个线程,但是子线程完全受主线程控制,且不得操作 DOM。所以,这个新标准并没有改变JS单线程的本质。

什么是异步任务异步任务就是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。

什么是事件循环事件循环(Event Loop)是 JavaScript 引擎处理异步任务的机制。它用来管理所有的任务队列,包括宏任务和微任务队列。当 JavaScript 引擎遇到异步任务时,会将其放入相应的任务队列中,并继续执行同步代码,直到同步代码执行完毕或遇到下一个异步任务。当当前的宏任务执行完毕后,JavaScript 引擎会按照一定的规则从微任务队列中取出任务执行,直到微任务队列为空;然后再从宏任务队列中取出下一个宏任务执行。这个过程就是事件循环。

宏任务和微任务都有宏任务有事件的回调函数,新程序或子程序被直接执行

事件循环流程整体script作为第一个宏任务进入主线程,遇到console.log(Start),输出Start遇到setTimeout,其回调函数被分发到宏任务中遇到newPromise,new Promise构造函数执行,输出"这是Promise构造函数"遇到then被分发到微任务中遇到console.log("End"),输出End调用栈被清空以后 事件循环就会优先寻找微任务队列里面的任务我们发现了then在微任务里面,执行输出“这是Promise.then”第一轮事件循环结束,开始第二轮事件循环宏任务有setTimeout对应的回调函数,立即执行输出“这是定时器”输出结果Start这是Promise构造函数End这是Promise.Then这是定时器这次来个复杂的例子 宏任务嵌套微任务 微任务嵌套宏任务 这次把script这个大宏任务忽略 以同步任务角度开始看async function async1 {console.log("async1 start");await async2;console.log("async1 end");}async function async2 {console.log("async2");}console.log("script start"); setTimeout(function {console.log("setTimeout1");});setTimeout(function {console.log("setTimeout2");Promise.resolve.then( => {console.log("then1");});Promise.resolve.then( => {console.log("then2");});}); async1;new Promise((res) => {console.log("this is Promise");res;}).then( => {console.log("then3");setTimeout( => {console.log("then3 setTimeout3");});});console.log("script end");

遇到函数async1 async2没有执行跳过遇到console.log('script start'),输出script start遇到setTimeout1其回调函数分发到宏任务中遇到setTimeout2其回调函数分发到宏任务中遇到async1函数执行, 遇到console.log("async1 start"),输出async start在async1函数中遇到await async2 async2优先级高于await运算符 async2函数执行在async2函数中遇到console.log("async2")输出 async2回到async1函数中 ,由于async函数使用await后的语句会被放入一个回调函数中,所以await后续代码分发到微任务中遇到new Promise构造函数中 console.log("this is Promise"),直接执行 输出this is Promisethen方法被分发到微任务中遇到console.log("script end")同步任务执行完了 开始执行异步任务 根据eventloop先执行任务队列中的微任务任务队列先入先出 所以先输出'async1 end' 后输出 new Promise.then中的内容 then3,new Promise.then中遇到setTimeout放到宏任务队列中,事件循环第一轮结束,开始第二轮宏任务队列setTimeout1拿出来输出事件循环第二轮结束,开始第三轮setTimeout2 执行 输出setTimeout1和setTimeout2setTimeout2中有两个.then方法分发到微任务 再执行输出 then1和then2事件循环第三轮结束,开始第四轮最后一个宏任务 输出 then3 setTimeout3所以代码输出结果script startasync1 startasync2this is Promisescript endasync1 endthen3setTimeout1setTimeout2then1then2then3 setTimeout3需要注意的是,微任务的执行顺序是按照它们被添加到微任务队列的顺序来执行的。即使某个微任务的产生时间晚于其他微任务,但如果它被添加到队列较早,那么它仍然会先于其他微任务执行。

文章到这里就结束了,希望对你有所帮助

转载此文是出于传递更多信息目的。若来源标注错误或侵犯了您的合法权益,请与本站联系,我们将及时更正、删除、谢谢。
https://www.414w.com/read/220822.html
0
随机主题
浙江永强:拟不超5000万美元在新加坡投资设立子公司0-3! 奥预赛黑马惨败, NO.2被横扫, 亚洲首败, 史诗级决胜局诞生数学王子:高斯的平凡出身与非凡之旅始祖鸟立大功, 萨洛蒙抄作业, 母公司亚玛芬中国业绩猛涨三国杀:这才是真正的毒绣,以前我们都错了《披哥4》曝光嘉宾名单, 李佳琦黑泽良平在列, 李克勤带队大咖少北京市首次 翠湖湿地公园来“新客”一周致命骚乱后, 马克龙亲赴海外领地: 设立一个“特派团”股价跌至1.7元, 连22年现金分红+股息率达4%, 国资买进前十股东海贼王1115话: 路飞跑路, 索隆娜美将会合, 金星摧毁艾尔巴夫船首全新宝腾S70 R3赛车亮相, 将重返S1K耐力赛!拜登不满国际刑事法院,扎哈罗娃嘲讽:“陷入自己网中的蜘蛛”4-1, 6-3! 曼城太强, 7次吊打曼联, 足总杯151亿决战, 央视不直播桃园三结义:关羽誓死效忠刘备,张飞:俺也一样!布林肯松口可使用美国武器袭击俄国本土: 乌克兰将做出自己的决定全新凯迪拉克XT5要来了, 或5月27日上市, 换装9K曲面屏, 外观升级5月23日人民币对美元中间价报7.1098 下调21个基点阿布扎比ADGM 2024年第一季度管理资产破纪录《庆余年2》范闲收服桑文, 他还不知, 桑文让他将来得以掌控庆国5月24日地狱火重燃! 168碎片新选择, 廉颇黄金金牛座来袭有人认为职业年金是私分国有资产的由头, 你认为这种说法靠谱吗?
最新回复(0)