美文网首页让前端飞Web 前端开发
对于事件循环机制的补充

对于事件循环机制的补充

作者: ac68882199a1 | 来源:发表于2018-04-01 20:17 被阅读46次

在之前的一篇文章中,小次简单的介绍了 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
<p id="test"></p>

// javascript
const $test = document.getElementById('test')
let counter = 0

function 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

扫码关注微信公众号【前端程序员的斜杠青年进化录】 微信扫码,给我赞赏一下~

相关文章

  • 对于事件循环机制的补充

    在之前的一篇文章中,小次简单的介绍了 Javascript 中的 Event Loop,没看过的小伙伴可以点击下方...

  • 并发:事件循环 & asyncio

    1. 事件循环机制 1.1. 什么是事件循环 事件循环(Event Loop),即通过轮询方法监控事件; asyn...

  • 《浏览器工作原理与实践》学习笔记(四)

    消息队列和事件循环 要想在线程运行过程中,能接收并执行新的任务,就需要采用事件循环机制。 事件循环机制:相比于线性...

  • 事件循环机制

    同步任务和异步任务 同步任务 即可以立即执行的任务,例如 console.log() 打印一条日志、声明一个变量或...

  • 事件循环机制

    js是单线程的。浏览器: js执行线程:负责执行js代码 UI线程:负责UI展示,负责展示给用户看到的页面 js事...

  • 事件循环机制

    事件循环(evenloop) 事件循环机制是宿主环境提供的。js中处理异步,增加了任务队列的概念(你不知道的js中...

  • 事件循环机制

    静下心学了一波事件循环机制,好开心,我学会了,首先还是得感谢作者写的笔记特别详细 链接: http://www.c...

  • 事件循环机制

    Javascript是单线程执行的,出现异步时,并不会阻塞JS的执行,而是接着往下执行,等到异步结果返回时再处理。...

  • 事件循环机制

    JS 有个全局的函数执行栈,这是执行同步函数的地方 除了函数执行栈,还有一个事件队列,这是执行异步函数的地方 异步...

  • 事件循环机制

    想要了解javascript的事件循环机制,首先从基础概念出发;关于线程和进程 进程好比图中的工厂;有单独的的自己...

网友评论

    本文标题:对于事件循环机制的补充

    本文链接:https://www.haomeiwen.com/subject/wmeacftx.html