浏览器事件循环,基础面试中大部分都会问的,本文讲讲这个知识点。
事件循环是负责执行代码、收集和处理事件以及执行队列中的子任务的一套机制。
在事件循环机制中,使用的栈数据结构便是执行上下文栈,每当有函数被调用时,便会创建相对应的执行上下文并将其入栈;使用到堆数据结构主要是为了表示一个大部分非结构化的内存区域存放对象;使用到的队列数据结构便是任务队列,主要用于存放异步任务。如下图:
在JavaScript代码运行过程中,会进入到不同的执行环境中,一开始执行时最先进入到全局环境,此时全局上下文首先被创建并入栈,之后当调用函数时则进入相应的函数环境,此时相应函数上下文被创建并入栈,当处于栈顶的执行上下文代码执行完毕后,则会将其出栈。这里说的栈就是执行上下文。
在事件循环机制中,存在多种任务队列,其分为宏任务队列和微任务队列两种。
宏任务包括setTimeout、setInterval、I/O、UI rendering。
微任务包括Promise、Object.observe(已废弃)、MutationObserver(html5新特性)。
主线程执行JavaScript整体代码,形成执行上下文栈,当遇到各种任务源时将其所指定的异步任务挂起,接受到响应结果后将异步任务放入对应的任务队列中,直到执行上下文栈只剩全局上下文;
将微任务队列中的所有任务队列按优先级、单个任务队列的异步任务按先进先出的方式入栈并执行,直到清空所有的微任务队列;
将宏任务队列中优先级最高的任务队列中的异步任务按先进先出的方式入栈并执行;
重复第 2 3 步骤,直到清空所有的宏任务队列和微任务队列,全局上下文出栈。
简单来说,事件循环机制的流程就是,主线程执行JavaScript整体代码后将遇到的各个任务源所指定的任务分发到各个任务队列中,然后微任务队列和宏任务队列交替入栈执行直到清空所有的任务队列,全局上下文出栈。
虽然Node.js也有事件循环,可是它和浏览器的事件循环完全不是一个东西。Node.js采用V8作为js的解析引擎,而I/O处理方面使用了自己设计的libuv,libuv是一个基于事件驱动的跨平台抽象层,封装了不同操作系统一些底层特性,对外提供统一的API,事件循环机制也是它里面的实现。这里不展开讲了,想了解的自己去看文档。
谢谢阅读!
推荐教程:《JS教程》
以上是浏览器的事件循环详解的详细内容。更多信息请关注PHP中文网其他相关文章!