xiaochengzi6 / Blog

个人博客
GNU Lesser General Public License v2.1
0 stars 0 forks source link

Event Loop #57

Open xiaochengzi6 opened 2 years ago

xiaochengzi6 commented 2 years ago

事件循环

事件循环两个关键概念:

  1. 宏任务
  2. 微任务

事件的执行顺序是先宏任务再微任务

宏任务

宏任务包含

  1. setTimeout
  2. setInterval
  3. setImmediate
  4. UI 交互
  5. I/O 流

微任务

  1. promise
  2. process.nextick()
  3. ...

当开始执行 JS 文件 文件时 这里的代码就可以被理解为是 宏任务 宏任务执行完 并且在此期间遇到所有的微任务存储到微任务队列 宏任务 存储到宏任务队列 由于宏任务的工作执行完 接下来就要执行微任务队列中的微任务并情况这里所有的微任务,也就是说执行一次宏任务要清空所有的微任务,在执行宏任务队列中的下一个宏任务重复之前的操作

由于 JS 执行环境不同所以对于任务队列的处理以及实现都有所不同 这里有 Node 环境浏览器环境 (chrom) image 比如下面这个例子

console.log(1)

setTimeout(() => {
    console.log(2)
    new Promise(resolve => {
        console.log(4)
        resolve()
    }).then(() => {
        console.log(5)
    })
    process.nextTick(() => {
        console.log(3)
    })
})
// 1 2 4 3 5

process.nextTick() 执行的优先级就要大于 Promise 的执行顺序

差异

Node 环境中 首先开始执行的就是宏任务也就是 setTimeout/setInterval 函数 执行完后开始执行 I/O 数据流 然后开始执行 setImmediate 事件 再执行 close handle queue 关闭事件的队列 其中开始执行 next tick queue 事件队列也就是 process.nextick() 事件 再执行其他的微任务队列比如Promise 并且要清空微任务队列也就是执行完这次宏任务保存的微任务的事件

浏览器环境中就是按照之前的规范流程就行但是需要知道里面的细节 比如浏览器在实现 setTimeout() 函数细节的时候它的差异时间是1ms 当五个以上的 setTimeout 嵌套时就会将时间间隔改为4ms 也就是说使用 setTimeout 时间间隔超过 1ms 的都会按照其时间顺序执行

xiaochengzi6 commented 2 years ago

关于node 环境和浏览器环境差异 这一块的知识点有些过时不过可以看一下文章 写的详细 EventLoop 阅读完上文关于更详细的差异node 环境 EventLoop