JavaScript 前端事件循环机制详解:从单线程到宏微任务

作者:像素漫游

时间:2026-10-26

浏览:309

本文详细解析 JavaScript 的单线程执行模型与事件循环机制,阐述消息队列、IO 线程及延迟任务队列的工作原理。重点对比宏任务与微任务的定义、执行时机及优先级,并深入分析 setTimeout 在浏览器环境中的实现细节与限制条件,帮助开发者掌握异步编程的核心逻辑。

文章目录

一、消息队列和事件循环

1.单线程处理机制

若任务序列确定,可采用单一线程按序执行,直至所有任务处理完毕并退出该线程。

int main(){
    int a, b;
    cin >> a;
    cin >> b;
    cout << a + b << endl;
    return 0;
}

2.事件循环机制

在单线程架构下,若需接收并处理新任务,必须引入事件循环机制以维持运行。

int main(){
    int a, b;
    while (true) {
        cin >> a;
        cin >> b;
        cout << a + b;
    }
    return 0;
}

3.消息队列

处理其他线程任务时,需借助消息队列进行中转。

消息队列属于一种数据结构,用于存储待执行任务,遵循“先进先出”原则:新任务追加至队尾,从队头取出执行。

主线程在执行期间,通过事件循环机制从消息队列中读取并执行任务。

4.IO线程

浏览器渲染进程中设有专门的 IO 线程,用于接收来自其他进程的消息。接收后,IO 线程将这些消息封装为任务,发送给主线程并加入消息队列。

5.页面使用单线程的缺点

(1)如何处理高优先级的任务

(2)如何解决单个任务执行时长过久的问题

二、setTimeout

1.浏览器怎么实现 setTimeout

除普通消息队列外,浏览器还维护一个延迟任务队列,涵盖定时器及 Chromium 内部需延迟执行的任务。当 JavaScript 创建定时器时,渲染进程会将对应回调任务加入该延迟队列。

加入延迟队列后,事件循环线程的执行流程调整为:先执行一次正常消息队列中的任务;若当前任务触发了延迟事件,则将其加入延迟任务消息队列;待该任务执行完毕后,依次执行延迟队列中已到期的任务,随后循环往复。

2.使用setTimeout的一些注意事项

(1)当前任务执行时间过长会影响定时器任务的执行。

(2)如果setTimeout存在嵌套调用,那么系统会设置最短时间间隔为4毫秒

(3)未激活的页面,setTimeout执行最小间隔是1000毫秒

(4)延时执行时间有最大值

三、宏任务和微任务

1.宏任务

渲染事件(如解析DOM、计算布局、绘制页面)

用户交互事件(点击、滚动、缩放)

JavaScript脚本执行事件

网络请求、文件读写完成

(1)事件循环机制

  • 先从消息队列中选出一个最老的任务,这个任务称为oldestTask
  • 然后循环系统记录任务开始执行时间,并将oldestTask设置为当前正在执行的任务
  • 当任务执行完成之后,删除当前正在执行的任务,并从消息队列中删除oldestTask
  • 最后统计执行完成的时长等信息

2.微任务

微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前。

  • Dom添加、删除等操作
  • Promise resolve和reject

(1)微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列。

(2)微任务的执行时长会影响到当前宏任务的时长

(3)在一个宏任务中,分别创建一个用于回调的宏任务和微任务,无论什么情况下,微任务都早于宏任务执行。

到此这篇关于Javascript前端事件循环机制详细讲解的文章就介绍到这了,更多相关Javascript事件循环机制内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章