对于事件循环机制的补充

对于事件循环机制的补充
文章图片
在之前的一篇文章中,小次简单的介绍了 Javascript 中的 Event Loop,没看过的小伙伴可以点击下方传送门:
Javascript 基础夯实——理解 Event Loop、Micro Task & Macro Task
上周有一位小伙伴来找小次对这个话题又进行了一番探讨,内容是关于在 Macro Task 执行时,如果有新的 Micro Task 入栈,那么这个新任务会在什么时间执行呢?
下面是一种可能存在的情况:

function macro () { setTimeout(() => { micro() }) }function micro () { new Promise.resolve().then(() => { ... }) }macro()

可能存在的情况
  1. 当前 Macro Task 栈中有多个任务时,新的 Micro Task 将会在所有 Marco Task 完成之后的下一次主任务及 UI 渲染之间执行
对于事件循环机制的补充
文章图片
  1. 新的 Micro Task 会在当前正在执行的 Macro Task 结束之后执行,并且如果 Micro Task 中有更新 UI 的任务,剩余的 Macro Task 会在 UI 更新完成后执行
对于事件循环机制的补充
文章图片
当然,情况可能并不只有上面两种。但是可以发现的是,上面两种情况中都没有提到 Main Task 的执行时机,因为只要 Main Task 存在,它就会在当前任务执行完毕后立即执行,优先级是最高的。
下面就验证一下上面两种情况的猜测是否正确。
验证代码
// html
// javascript const $test = document.getElementById('test') let counter = 0function func1 () { $test.innerText = ++counter alert('func1') }function func2 () { $test.innerText = ++counter alert('func2') }function func3 () { $test.innerText = ++counter alert('func3') }function func4 () { $test.innerText = ++counter alert('func4') }(function () { // main task func1()// macro task setTimeout(() => { func2() // micro task Promise.resolve().then(func4) Promise.resolve().then(func3) }, 0)// macro task setTimeout(func1, 0)// micro task Promise.resolve().then(func3)// main task func4() })()

上面的代码中,在 setTimeout 执行时,向 Micro Task 中添加了两个任务,并且不管是执行 Main Task,Macro Task 还是 Micro Task 都会对 UI 进行更新,这也能够更方便我们理清楚 UI 更新的时机。
【对于事件循环机制的补充】在代码中使用 alert,是为了能够更明显地看到 UI 更新的情况,因为 alert 会阻塞代码和 UI 的更新
下面直接看上面验证代码的执行情况:
1- alert func1 2- alert func4 3- alert func3 4- UI update -- counter = 3 5- alert func2 6- alert func4 7- alert func3 8- UI update -- counter = 6 9- alert func1 10 - UI update -- counter = 7

总结一下上面验证代码得出的结论:
如果在 Macro 中有新的 Micro 入栈,Micro 的执行总是在 Macro 之前,并且会在 Micro 全部执行完毕后才会更新 UI 和执行下一个 Macro
对于事件循环机制的补充
文章图片
扫码关注微信公众号【前端程序员的斜杠青年进化录】 对于事件循环机制的补充
文章图片
微信扫码,给我赞赏一下~

    推荐阅读