JS运行机制

本文深入解析JavaScript的事件循环机制,包括浏览器与Node.js环境下的异步处理方式,阐述宏任务与微任务的区别及执行顺序,帮助理解JS单线程背后的运行逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Javascript运行机制-浏览器事件循环与Node事件循环机制

var test1 = function(){
    alert(1);
}
var test2 = function(){
    alert(2);
}
setTimeout(function(){
   alert(3);
},1000);
test();
test2();
//打印出结果为: 1  2   3

上述代码为什么是这个结果呢?为什么不是 3 1 2呢,其实这就是JavaScript的运行机制导致的,我们都知道js是单线程的,但是我们却不一定知道为什么如此,首先我们先了解js为什么是单线程的呢?

JS为什么是单线程?

假设JS是多线程的,那么当我创建一个线程去为一个DOM节点添加属性或者样式时,同时创建另一个线程去删除这个DOM节点,此时浏览器是以哪个线程为主呢?这就是js为什么是单线程而不是多线程的原因。
下面我们来了解js的运行机制:

JS的运行机制:

因为JavaScript是单线程,意味着任务要一个接着一个完成,但是,如果前一个任务执行时间很长,那么后面的任务就得一直阻塞着,这样用户体验十分差。
JavaScript的设计者考虑到了这一点,所以他将JavaScript的任务分为两种,在主线程上执行的任务"同步任务",被主线程挂载起来的任务"异步任务",后者一般是放在一个叫任务队列的数据结构中。
只有当所有同步任务都执行完了才会,开始观察任务队列中被挂载起来的任务,并且按照队列的特性,先进先出的依次执行。

浏览器事件循环机制:

  • js 将 异步任务 队列内的任务 分为 宏任务微任务,宏任务备存在 jobs 队列中 ,微任务备存在 task队列中
  • 哪些是宏任务 ? script代码块 setTimeout ,setInterval,I/O, UI render 等,当遇到上述代码/操作 就会往 jobs(宏任务队列)队列中放置。
  • 哪些是微任务 ? promise , process.nextTick,MutationObserver 等,当遇到上述代码/操作 就会往 task(微任务队列)队列中放置。
  • 事件循环机制会影响代码的执行顺序。每一次事件循环 都是从一个 宏任务开始,当该宏任务内的执行栈执行完成,就会查看 task(微任务队列)队列内是否有可执行的方法,执行完这些微任务,那么一次事件循环就结束,进入下一次事件循环,又是从一个宏任务开始。反复重复这个操作直到所有任务执行完成,这就是js的事件循环。

Node事件循环机制:

在这里插入图片描述
从上图可以看出大致流程为:
外部输入数据–>轮询阶段(poll)–>检查阶段(check)–>关闭事件回调阶段(close callback)–>定时器检测阶段(timer)–>I/O 事件回调阶段(I/O callbacks)–>闲置阶段(idle, prepare)–>轮询阶段(按照该顺序反复运行)

阶段分析:

  1. timer 阶段: 主要执行设置的一些定时器,setTimeout/setInterval等。
  2. I/O callBack阶段:主要执行I/O操作的回调函数,例如文件读写。
  3. idle,prepare阶段:等待(闲置)阶段
  4. poll 阶段:轮询阶段,此时会获取I/O操作的回调,并将它们放入任务队列,如果此时队列中已经有上一次事件循环存入的任务等待被执行,则会循环执行完所有的任务。
  5. check 阶段:此时会执行setImmediate函数的回调c
  6. close callbacks 阶段:关闭事件回调阶段,此时会执行socket关闭的回调
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值