面试官😏: 讲一下事件循环 ,顺便做道题🤪

题目

倔友们一起看一下把 ~

面试官 : 讲一下事件循环 , 顺便做了一道题🤪:下面字母的输出顺序是什么 ?

js 复制代码
async function async1() {
  console.log('E'); 
  await async2();
  console.log('F');
}

async function async2() {
  console.log('G');
}

setTimeout(() => console.log('H'), 0);
async1(); 
new Promise((res) => {
  console.log('I'); 
  res();
}).then(() => console.log('J'))

这是一段涉及 JavaScript 中异步操作( async/await 、 Promise 、 setTimeout )的代码,要确定其执行顺序,需要了解这些异步机制的执行原理------ 事件循环机制(Event loop)

答案 : E 、 G 、 I 、 F 、 J 、 H

不清楚的倔友一起往下看 :

事件循环

事件循环是JavaScript中用于

  • 处理异步操作
  • 协调事件处理

在网页开发中,事件循环确保用户界面的响应性。例如,当用户点击按钮时,点击事件作为一个宏任务被放入任务队列,在合适的时机被处理。在处理网络请求时,发起请求是异步操作,不会阻塞其他代码执行,请求完成后,响应数据的处理函数会作为一个宏任务或微任务被放入任务队列,等待执行。

基本概念

JavaScript是单线程语言,同一时间只能执行一个任务,但可以通过事件循环来实现异步操作。事件循环允许JavaScript在执行同步任务的同时,处理各种异步任务,如网络请求、定时器、用户交互等,不会因为某个耗时的操作而阻塞整个程序的运行。

工作原理

  • 执行栈:也叫调用栈,是一种存储函数调用关系的数据结构。当函数被调用时,会被压入执行栈,函数执行完毕后从栈顶弹出。JavaScript引擎会按照顺序执行执行栈中的函数。
  • 任务队列 :包括宏任务队列和微任务队列。
    • 宏任务包括 setTimeout 、 setInterval 、 setImmediate (Node.js环境)、I/O操作、UI渲染等
    • 微任务包括 Promise 的回调、 MutationObserver 等
  • 循环机制 :事件循环首先会检查执行栈 是否为空,如果为空,则检查微任务队列 是否有任务。如果有微任务,就会依次执行微任务队列中的所有任务,直到微任务队列为空。然后,事件循环会检查宏任务队列,从宏任务队列中取出一个宏任务放入执行栈执行,执行完这个宏任务后,再次检查微任务队列并执行其中的任务,如此循环往复。

执行流程图

这张图说明了一下几个点 :

  • 同步代码先执行
  • 异步代码先执行宏任务 , 再执行微任务

这个时候 , 我们再来看这段代码的执行顺序 ,简直是有手就行 ~

首先执行同步代码,遇到 setTimeout(() => console.log('H'), 0); , setTimeout 会将其回调函数放入宏任务队列中,暂不执行。

接着调用 async1() ,进入 async1 函数,首先执行 console.log('E'); ,输出 E 。

然后遇到 await async2(); ,先执行 async2 函数, async2 函数中 console.log('G'); ,输出 G 。此时 await 会暂停 async1 函数的执行,将 async1 函数中 await 后面的代码( console.log('F'); )放入微任务队列中。

继续执行同步代码,遇到 new Promise((res) => { console.log('I'); res(); }).then(() => console.log('J')); , Promise 的构造函数中的 console.log('I'); 会立即执行,输出 I ,并且 Promise 状态变为 fulfilled ,其 then 回调函数会被放入微任务队列中。

此时同步代码执行完毕 ,开始处理微任务队列。先执行 async1 函数中 await 后面被放入微任务队列的 console.log('F'); ,输出 F 。

接着执行 Promise 的 then 回调函数 console.log('J'); ,输出 J 。

微任务队列处理完毕后 ,开始处理宏任务队列,执行 setTimeout 的回调函数 console.log('H'); ,输出 H 。

综上所述,这段代码的执行顺序是: E 、 G 、 I 、 F 、 J 、 H 。

总结

两个点

  • 顺序 :同步代码 => 微任务 => 宏任务
  • 循环 :宏任务 => 微任务 , 没有微任务继续执行宏任务
相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax