JavaScript 的事件循环、宏任务、微任务

JavaScrtipt 执行顺序

首先,必须要明确,在JavaScript中,所有任务都在主线程上执行。任务执行过程分为同步任务异步任务两个阶段。异步任务的处理经历两个主要阶段:Event Table(事件表)和 Event Queue(事件队列)。Event Table存储了宏任务的相关信息,包括事件监听和相应的回调函数。当特定类型的事件发生时,对应的回调函数被添加到事件队列中,等待执行。例如,你可以通过addEventListener来将事件监听器注册到事件表上。
执行流程图
image

事件循环

  1. 概念:在事件循环中,当主线程执行完当前的同步任务后,会检查事件队列中是否有待处理的事件。如果有,主线程会取出事件并执行对应的回调函数。这个循环的过程被称为事件循环(Event Loop),它由主线程和任务队列两部分组成。主线程负责执行同步任务,而异步任务则通过任务队列进行处理。这种机制保证了异步任务在适当的时机能够插入执行,从而实现了JavaScript的非阻塞异步执行。
  2. 通俗:事件循环是什么?为什么要有事件循环这个东西?我们都知道JS是单线程的,但是像Ajax,或是DOM事件这种很耗时的操作,需要用并发处理,否则单线程会长时间等待,什么也做不了。而单线程循环就是并发的一种形式,一个线程中只有一个事件循环。而任务队列是用来配合事件循环完成操作的,一个线程可以拥有多个任务队列
  3. 执行步骤:
    事件循环的tick机制是指事件循环在每个迭代中执行的操作。一个tick通常包括以下步骤:
    执行栈清空:JavaScript引擎首先执行执行栈中的所有同步任务。
    微任务执行:执行栈清空后,事件循环会执行所有可用的微任务。
    宏任务执行:微任务执行完毕后,事件循环会从宏任务队列中取出一个任务并执行。
    渲染更新:在浏览器环境中,UI渲染可能会在每个tick之后发生,以更新浏览器界面。
    image

任务队列

任务队列是什么?故名思意,排着任务的队列。所谓任务是WebAPIs返回的一个个通知,让JS主线程在读取任务队列的时候得知这个异步任务已经完成,下一步该执行这个任务的回调函数了。主线程拥有多个任务队列,不同的任务队列用来排列来自不同任务源的任务。任务源是什么?像setTimeout/Promise/DOM事件等都是任务源,来自同类任务源的任务我们称它们是同源的,比如setTimeout与setInterval就是同源的。在ES6标准中任务队列又分为宏观任务队列和微观任务队列

概括

js有两种任务,同步任务和异步任务;异步任务通过任务队列机制来执行代码;任务队列里面分微任务和宏任务。宏任务是由宿主发起的,而微任务由JavaScript自身发起。
微任务:promise process.nextTick() Proxy MutaionObserver
宏任务:setTimeout \ setInterval \ setImmediate \ I/O \ UI交互 、 DOM事件 、 网络请求

参考资料

  1. 什么是宏任务、微任务?宏任务、微任务有哪些?又是怎么执行的?
  2. 一次搞懂-JS事件循环之宏任务和微任务
  3. JavaScript事件循环机制(event loop)、宏任务、微任务总结
  4. JS的执行原理,一文了解Event Loop事件循环、微任务、宏任务
  5. 宏任务、微任务和同步代码的执行关系与事件循环 流程机制详解
posted @ 2024-08-27 09:52  拉布拉多~  阅读(37)  评论(0编辑  收藏  举报