事件循环机制在事件循环中,每个循环操作称为tick,每个tick的任务处理比较复杂,但关键步骤如下:执行一个宏任务(如果有则从事件队列中获取不在栈中))如果在执行过程中遇到了microtask,则将其添加到microtask的任务队列中。macrotask执行完毕后,会立即执行当前microtask队列中的所有microtasks(顺序执行)。当前macrotask执行完后,开始勾选Rendering,然后GUI线程接管渲染。渲染完成后,JS线程继续接管并开始下一个宏任务(从事件队列中获取)。流程图如下:那么什么是宏任务和微任务呢?宏任务(也称宏任务),可以理解为执行栈每次执行的代码都是一个宏任务(包括每次从事件队列中获取事件回调放入执行栈执行)Browse为使JS内部(宏)任务和DOM任务有序执行,(宏)任务会在一个(宏)任务执行完成后,下一个(宏)任务执行前重新渲染页面)任务开始。包含:script(整体代码)、setTimeout、setIntervalmicrotaskmicrotask(也称microtask),可以理解为当前(宏)任务执行结束后立即执行的任务。也就是说,在当前(宏)任务之后,在下一个(宏)任务之前,以及渲染之前。所以它的响应速度会比setTimeout快(setTimeout是(宏)任务),因为不需要等待渲染。也就是说,一个macrotask执行完之后,所有在它执行过程中产生的microtask都会被执行(渲染之前)。microtask主要包括:Promise.then,await方法背后的代码属于.then(await相当ForaPromise)栗子asyncfunctionasync1(){console.log('A');等待async2();console.log('B');}asyncfunctionasync2(){console.log('C');}console.log('D');setTimeout(function(){console.log('E');});async1();newPromise(function(resolve){console.log('F');resolve();}).then(function(){console.log('G');});console.log('H');首先,我们需要了解以下几点。任务队列主要包括以下三个,macroTaskqueue,microtaskqueue,executionstack一开始执行栈,而microtask队列是空的,macrotask只有一个脚本代码块。当执行栈为空时,将下一个macrotask添加到执行栈中,开始运行macrotask脚本程序往下执行,遇到console.log('D')。此时直接打印结果为://D然后继续执行,遇到setTimeout。属于宏任务,先加入宏任务队列。队列状态如下Executionstack:scriptmacrotaskqueue:setTimeoutmicrotaskqueue:empty继续往下执行,遇到async1()方法,运行这个方法,遇到console.log('A'),直接打印结果is://DA继续执行遇到async2()方法,运行这个方法遇到console.log('C'),直接打印结果为://DACasync2()方法中的程序全部执行完,又回到上一层async1()中,遇到console.log('B'),它在awaitasync2()后面,所以是异步的,加入microtask队列,然后返回最外层task队列状态如下执行栈:洪仁脚本taskqueue:setTimeoutmicrotaskqueue:console.log('B')继续执行,遇到newPromise(),本作用域内的同步任务执行作用域内的方法,遇到console.log('F'),打印直接结果是://DACF继续执行,遇到.then是异步的。然后将里面的代码添加到微任务队列中。任务队列的状态如下。Executionstack:scriptmacrotaskqueue:setTimeoutmicrotaskqueue:console.log('B'),console.log('G')执行新的Promise方法,回到上一个外面,遇到console.log('H'),直接打印结果为://DACFH当前脚本代码块程序执行完毕,即当前宏任务执行完毕。在宏任务执行过程中,如果一个微任务就绪,它会标记一个就绪状态,并将就绪的微任务从微任务队列中添加到执行栈中。任务队列的状态如下:console.log('B'),console.log('G')宏任务队列:setTimeout微任务队列:清空开始执行栈中的运行任务,执行在命令并直接打印结果://DACFHBG任务队列状态如下Executionstack:EmptyMacrotaskqueue:setTimeoutMicrotaskqueue:Empty当前执行栈为空,则将宏任务队列中的setTimeout加入执行栈。运行setTimeout时,遇到console.log('E'),直接打印结果为://DACFHBGE当前执行栈已经执行完毕,查看是否有微任务(无),查看是否有宏任务(不)。整个程序执行完后,这个问题留下一个问题,假设多个setTimeout的延迟执行时间不同,如何执行呢?参考资料来自一个关于JavaScript事件循环的问题文章内容/灵感借鉴自下面的内容【持续维护/更新500+前端面试题/笔记】https://github.com/noxussj/中...[大数据可视化图表插件]https://www.npmjs.com/package...[使用THREE.JS实现3D城市建模(珠海市)]https://3d.noxussj.top/