宏任务和微任务
宏任务和微任务
微任务 --- microtask称为jobs, 宏任务 --- macrotask称为task, 宏任务是由宿主发起的,而微任务由JavaScript自身发起。
常见的面试题:
console.log('start') setTimeout(()=>{ console.log('setTimeout') },0) new Promise((resolve)=>{ console.log("promise"); resolve(); }).then(()=>{ console.log("then1"); }).then(()=>{ console.log("then2"); }) console.log("end");
它的顺序是
start promise end then1 then2 setTimeout
实践
解:
Event Loop中,每一次循环称为tick,每一次tick的任务如下:
执行栈选择最先进入队列的宏任务,执行其同步代码直至结束;
检查是否存在微任务,有则会执行微任务队列为空;
如果宿主为浏览器,可能会渲染页面;
开始下一轮tick,执行宏任务中的异步代码;
setImmediate 和 process.nextTick 为Node环境下常用的方法,所以基于Node宿主分析。
( Node.js是运行在服务端的js,虽然用到也是v8引擎,但由于服务目的和环境不同,导致了它的API和原生JS有些区别,其EventLoop还要处理一些I/O,比如新的网络连接等。)
执行顺序如下:
1、timers: 执行setTimeout和setInterval的回调。
2、pending callbacks:执行延迟到下一个循环迭代的I/O回调。
3、idle prepare:仅系统内部使用。
4、poll:检索新的I/O事件;执行与I/O事件相关的回调。
5、check: setImmediate在这里执行。
6、close callbacks: 一些关闭的函调函数
setImmediate和setTimeout
console.log("outer"); setTimeout(() => { setTimeout(() => { console.log("setTimeout"); },0); setImmediate(() => { console.log("setImmediate") }) },0)
其执行顺序为:
1、外层是一个setTimeout,所以执行它的回调函数已经在timers阶段了。
2、处理里边的setTimeout,因为本次循环的timers正在执行,所以其回调其实加到了下一级timers阶段
3、处理里边的setImmediate,将它的回调加入check阶段的队列。
4、外层timers阶段处理完,进入pending callbacks,idle,prepare,poll,这几个队列都是空的,所以继续住下到了check阶段,发现了setImmediate的回调,拿出来执行
5、然后是close callbacks,队列是空的,跳过
在Node里边对setTimeout的特殊处理,setTimeout(fn, 0)会被强制改为setTimeout(fn, 1)
1、遇到setTimeout,虽然设置的是0毫秒触发,但是被node.js强制改为1毫秒,塞入timers阶段。
2、遇到setImmediate塞入check阶段。
3、同步代码执行完毕,进入Event Loop
4、先进入timers阶段,检查当前时间过去了1毫秒没有,如果过了1毫秒,满足setTimeout条件,执行回调,如果没过14毫秒,跳过。
5、跳过空的阶段,进入check阶段,执行setImmediate
可见,1毫秒是个关键点,所以,setImmediate不一定在setTimeout之前执行了。
promise 和 process.nextTick
因为 process.nextTick 为node环境下的方法,是一个特殊的异步API,其不属于任何的Event Loop阶段。
事实上Node在遇到这个API时,Event Loop根本不会继续进行,会马上停下来执行process.nextTick( ), 这个执行完才会继续Event Loop。所以,nextTick 和 Promise 同时出现,肯定是nextTick先执行,原因是nextTick的队列比Promise队列优先级更高。
vue实例的nextTick( )方法接受一个回调函数作为参数,用于将回调延迟到下次DOM更新周期之后执行。这个API就是基于事件循环实现的。下次DOM更新就是下次微任务执行时更新DOM,而vm.$nextTick就是将回调函数添加到微任务中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端