EventLoop

3/21/2022 js

# 1. EVENTLOOP任务

查看答案

# 宏微任务

JavaScript的任务横向分两种,宏任务(macro-task)微任务(micro-task)

  • 宏任务:是主线程,形成执行栈。
    • 包括整体代码script,setTimeout,setInterval,I/O事件,postMessage,setImmediate,requestAnimationFrame,UI渲染
  • 微任务:不进主线程,进入任务队列。
    • Promise.then(非new Promise),process.nextTick(node中),MutationObserver

执行的优先级:宏任务 > 微任务 事件的执行顺序,都是先把宏任务执行完成之后,才回去判断是否有可执行的微任务。如果没有微任务的情况下,就会去执行下一个宏任务。

# 同异任务

任务纵向分两种,有 同步任务异步任务

  • 如果任务是同步任务,那么可以直接进入主线程。
  • 如果任务是异步任务,那么会进入到Event Table中,Event Table会把所有的异步任务做一个声明和聚集,异步事件完成后,会将回调函数放入Event Queue中(宏任务和微任务是不同的Event Queue),当主线程执行完同步任务之后会从event queue中拿出任务放入主线程中继续执行,回调函数中可能还会包含不同的任务,因此会循环执行上述操作。

# 2. setTimeout、Promise、Async/Await 的区别

查看答案
  • new Promise是同步的任务,会被放到主进程中去立即执行
  • .then()函数是异步任务,当你的promise状态结束的时候,就会立即会放到异步队列中去
  • 带async关键字的函数会返回一个promise对象,如果里面没有await,执行起来等同于普通函数
  • await 关键字要在 async 关键字函数的内部,await 写在外面会报错;await如同他的语意,就是在等待,等待右侧的表达式完成。此时的await会让出线程,阻塞async内后续的代码,先去执行async外的代码。等外面的同步代码执行完毕,才会执行里面的后续代码。

# 3. 为什么setTimeout为什么不能精准的执行?

查看答案

setTimeout执行需要满足两个条件:

  1. 主进程必须是空闲的状态,如果到时间了,主进程不空闲也不会执行你的回掉函数
  2. 这个回掉函数需要等到插入异步队列时前面的异步函数都执行完了,才会执行

setTimeout并不是直接的把你的回掉函数放进上述的异步队列中去,而是在定时器的时间到了之后,把回掉函数放到执行异步队列中去。如果此时这个队列已经有很多任务了,那就排在他们的后面。

setTimeout的最小延迟时间为4ms,所以在4ms内,还是会按照执行顺序执行。

# 4. 说说浏览器和 Node 事件循环的区别

查看答案

其中一个主要的区别在于浏览器的 event loop 和 nodejs 的 event loop 在处理异步事件的顺序是不同的。 nodejs 中有 micro event,其中 Promise 属于 micro event 该异步事件的处理顺序就和浏览器不同。 nodejs V11.0 以上 这两者之间的顺序就相同了。

更新时间: 2024-06-12 11:00