js 事件循环相关执行顺序

本文详细探讨了JavaScript中的事件循环机制,包括浏览器和Node.js的事件循环区别。阐述了process.nextTick()、微任务、宏任务(setTimeout等)的执行顺序,并通过实例解析了异步操作如何影响执行流程。最后,文章通过终极面试题来巩固对事件循环的理解,强调了不同场景下setTimeout与setImmediate的执行优先级。

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

javascript node 事件循环相关执行顺序

最近笔试某小游戏厂的时候遇见 node event loop 相关的题. 烟雨仔一直认为自己对 event loop 已经很了解了, 但还是入了坑.

在阅读这篇文章之前, 如果你是想了解 浏览器node event loop 更加底层的内容, 那么请移步至 node 官方. 本篇只适合想要对 node.js event loop 相关执行顺序略有了解的新手.

1. 浏览器 event loop

以下代码在众多的面试笔试题中, 是挺常见的. 在 chrome 浏览器中按序应该打印:

start ;
async1 start;
async2;
promise1;
script end;
async1 end;
promise2;
setTimeout

(说明一点: 只能保证在 chrome 浏览器中打印顺序如此, 烟雨仔尝试了诸如 QQ浏览器, 打印顺序有些微差异.)

	async function async1() {
   
      console.log("async1 start")
      await async2()
      console.log("async1 end")
    }
    async function async2() {
   
      console.log("async2")
    }
    console.log("start")
    setTimeout(() => {
   
      console.log("setTimeout")
    })
    async1
### 事件循环机制的执行顺序 JavaScript事件循环机制(Event Loop)是其核心特性之一,用于协调同步和异步任务执行。以下是关于事件循环机制执行顺序的具体解释: #### 1. **调用栈与任务队列** 当一段 JavaScript 代码运行时,所有的函数调用都会被压入调用栈中并依次执行[^3]。如果某个操作无法立即完成(如网络请求或定时器),则会被放置到对应的任务队列中等待后续处理。 #### 2. **微任务与宏任务的区别** - **微任务(Micro Tasks)**:这些任务具有更高的优先级,会在当前宏任务完成后立刻被执行。常见的微任务包括 `Promise.then` 和 `queueMicrotask()`。 - **宏任务(Macro Tasks)**:这些任务会稍后执行,通常涉及浏览器渲染或其他耗时操作。典型的宏任务有 `setTimeout`、`setInterval` 和 DOM 渲染更新等[^4]。 #### 3. **具体执行流程** 事件循环按照以下顺序逐步推进: 1. 当前宏任务中的代码完全执行完毕后,引擎会清空所有可用的微任务队列[^5]。 ```javascript console.log('Step A'); Promise.resolve().then(() => console.log('Step B')); console.log('Step C'); ``` 输出结果为: ``` Step A Step C Step B ``` 2. 如果没有剩余的微任务,则继续从任务队列中取出下一个宏任务进行处理[^2]。 3. 特殊情况下,某些特定类型的回调可能拥有额外的优先权。例如,在 Node.js 中,`process.nextTick` 总是在其他任何任务之前触发[^4]。 #### 4. **Node.js 环境下的扩展** 对于基于 V8 引擎构建的应用程序来说,比如 Node.js 平台上的脚本文件,还存在更细化的时间段划分方法。其中包括但不限于以下几个阶段: - Timers 阶段:此期间可以调度那些已经超时的计时器; - Polling 阶段:主要用于轮询待定 I/O 操作的状态变化情况; - Checkpoint 阶段:允许开发者注册一些自定义逻辑以便适时介入整个生命周期过程之中;等等。 --- ### 示例代码演示 下面提供了一段综合性的测试代码来展示不同种类任务之间的相互关系及其最终表现形式如何受到上述规则的影响: ```javascript console.log('Script start'); setTimeout(function() { console.log('Timeout 1'); }, 0); new Promise(resolve => { console.log('Before promise resolution'); resolve(); }).then(() => { console.log('Resolved promise'); }); setTimeout(function() { console.log('Timeout 2'); }, 0); console.log('Script end'); ``` 预期输出如下所示: ``` Script start Before promise resolution Script end Resolved promise Timeout 1 Timeout 2 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值