首页 web前端 js教程 技术面试问题 - 部分事件循环

技术面试问题 - 部分事件循环

Nov 29, 2024 am 11:45 AM

介绍

大家好!

今天,正如标题所说,我将讨论事件循环。

这不是面试官经常直接询问的话题(我只记得有两次他们让我解释事件循环)。但是,在大多数采访中,他们会提出与之相关的问题。例如:

  • “如果我这样做……应该有什么行为?”
  • “如果我的代码如下所示,输出会是什么?”
  • “为什么这段代码会产生这样的输出?”

如果您了解事件循环的工作原理,那么所有这些问题都会更容易回答。

老实说:这个话题不是我最喜欢的。我更喜欢询问有关代码行为的问题,而不是解释事件循环如何连续工作 10 分钟。?

Technical Interview Questions - Part  Event Loop

让我们开始吧! ?

## 问题
1.什么是事件循环?
2. 示例


什么是事件循环?

简短回答:

事件循环负责处理 JavaScript 运行时中的异步任务。

说实话,我认为这个答案不足以满足面试官询问事件循环的好奇心。因此,在这篇文章中,我想更深入地探讨这个主题。

不仅仅是了解概念,了解如何它的工作原理也很重要。这就是为什么我在最后添加了一些示例。

Technical Interview Questions - Part  Event Loop

理论

什么是事件循环?

JavaScript 有一个基于事件循环的运行时,负责处理任务。每种语言都有独特的运行时,需要注意的重要一点是 JavaScript 是单线程

单线程是什么意思?

单线程意味着JavaScript 一次只能处理一项任务。这就是为什么事件循环在 JavaScript 中如此重要;尽管存在单线程限制,它仍然有助于有效地管理任务。

运行时的组成部分

为了更好地理解事件循环,我们首先看一下它的主要组成部分:

Technical Interview Questions - Part  Event Loop

调用栈

调用堆栈是一种数据结构,用于跟踪我们调用的函数。你可以把它想象成一堆盘子:当一个函数被调用时,它被添加到堆栈中,当它完成时,它被从堆栈中删除。

调用堆栈遵循 LIFO(后进先出) 原则,这意味着 JavaScript 按照函数的堆叠顺序执行函数 — 从最上面的项到底部,一个位于一次(记住,JavaScript 是单线程的)。

队列

在 JavaScript 的运行时中,我们有队列,它保存要处理的任务列表。这些队列中的任务会等待,直到调用堆栈为空。

  • 任务队列(或回调队列):此队列存储诸如 setTimeout() 和 setInterval() 调用之类的任务。这里的任务是在调用堆栈为空并且微任务队列中的所有任务都处理完之后进行处理的。在 MDN 上查看存储在此队列中的任务的更多示例。

  • 微任务队列: 该队列的优先级高于任务队列。它包括微任务(例如 Promise 回调)和异步函数(例如 process.nextTick() 和异步函数)。

任务队列FIFO(先进先出)为基础工作,这意味着任务按照添加的顺序进行处理,但仅在微任务之后进行队列已空。

事件循环

事件循环是一种管理异步代码执行的机制。它观察调用堆栈以及调用堆栈和队列(任务队列和微任务队列)之间的协调,以保持代码顺利运行。

它是如何运作的?

让我们一步步过一遍事件循环过程。请参阅下图以获得直观表示。

Technical Interview Questions - Part  Event Loop

在此示例中:

  • 调用堆栈只有一个功能。
  • 微任务队列有两条消息。
  • 任务队列有一条消息。

第 1 步:处理调用堆栈

  1. 事件循环从查看调用堆栈开始。
  2. 它在堆栈中找到一个函数并开始执行它。
  3. 此函数完成后,就会从调用堆栈中删除。

Technical Interview Questions - Part  Event Loop

第2步:处理微任务队列

  1. 调用堆栈为空后,事件循环会检查微任务队列
  2. 它从微任务队列获取第一条消息并将其推送到调用堆栈来执行。

Technical Interview Questions - Part  Event Loop

  1. 该函数运行,一旦完成,就会从调用堆栈中删除。
  2. 事件循环然后移动到微任务队列中的下一条消息并重复该过程。
  3. 这会一直持续到微任务队列中不再有消息为止。

Technical Interview Questions - Part  Event Loop

第三步:处理任务队列

  1. 一旦调用堆栈微任务队列都为空,事件循环就会转向任务队列
  2. 它选择任务队列中的第一条消息并将其添加到调用堆栈
  3. 函数运行,完成后,它会从调用堆栈中删除。
  4. 事件循环将对任务队列中的每个任务继续此过程,确保所有任务都被一一处理。

Technical Interview Questions - Part  Event Loop

按照这个顺序——调用堆栈,然后微任务队列,最后任务队列——事件循环帮助JavaScript有效地处理异步代码,即使在它的单线程环境。


示例

现在我们了解了事件循环的工作原理以及任务的优先级如何确定,让我们看一些示例。

实施例1

const a = new Promise(function showA(resolve){
  console.log('A');
  resolve('B');
});

setTimeout(function showC() {
  console.log('C');
}, 0);

a.then(function showB(b) {
  console.log(b);
});

const d = function showD() {
  console.log('D');
};

d();
登录后复制
登录后复制

在继续之前,尝试考虑一下输出的顺序。

✨你期望它是什么?✨

让我们分解代码的每个部分来理解为什么我们会得到这个输出。

1。创造承诺

const a = new Promise(function showA(resolve) {
  console.log('A');
  resolve('B');
});
登录后复制
登录后复制
  • 在这里,我们创建一个带有回调函数的新 Promise。
  • 在此函数内,console.log('A') 会立即执行,因此 "A" 会打印到控制台。
  • 记录“A”后,promise 被解析为值“B”。
  • JavaScript 识别出有一个 .then 回调(即 showB),一旦主调用堆栈清除,该回调应该运行,因此它将 showB 添加到 微任务队列(因为 Promise 解析会去那里)。

2。 setTimeout 调用

setTimeout(function showC() {
  console.log('C');
}, 0);
登录后复制
登录后复制
  • setTimeout 函数安排 showC 在 0 毫秒后运行。
  • JavaScript 将 showC 放入任务队列中,因为它是一个基于计时器的函数。

3。 a.then 回调

const a = new Promise(function showA(resolve){
  console.log('A');
  resolve('B');
});

setTimeout(function showC() {
  console.log('C');
}, 0);

a.then(function showB(b) {
  console.log(b);
});

const d = function showD() {
  console.log('D');
};

d();
登录后复制
登录后复制
  • 这一行为我们在上一步中已经解决的 Promise 注册了一个 .then 处理程序 (resolve('B'))。
  • 由于 Promise 已解决,showB(.then 回调)被添加到 微任务队列

4。定义 d

const a = new Promise(function showA(resolve) {
  console.log('A');
  resolve('B');
});
登录后复制
登录后复制
  • 这一行只是定义了函数 showD 但尚未执行它,所以这里什么也没有发生。

5。调用 d()

setTimeout(function showC() {
  console.log('C');
}, 0);
登录后复制
登录后复制
  • 现在,我们调用 d(),它被添加到 调用堆栈 并执行。 这会产生 console.log('D'),因此 "D" 会打印到控制台。

最终输出顺序:

a.then(function showB(b) {
  console.log(b);
});
登录后复制

GIF供参考

Technical Interview Questions - Part  Event Loop
互动示例

实施例2

const d = function showD() {
  console.log('D');
};
登录后复制

再次花点时间考虑一下输出的顺序。

✨你期望它是什么?✨

让我们来解释一下......

1。记录“开始!”

d();
登录后复制
  • 这行代码被添加到调用堆栈并立即执行。
  • 结果,“开始!” 被打印到控制台。
  1. 设置超时调用
A
D
B
C
登录后复制
  • setTimeout 函数安排 showTimeout 在 0 毫秒后运行。
  • JavaScript 将 showTimeout 放置在 任务队列 中,因为它是一个基于计时器的函数。

3。承诺决议

console.log("Start!");

setTimeout(function showTimeout() {
  console.log("Timeout!");
}, 0);

Promise.resolve("Promise!")
  .then(function showPromise(res) {
    console.log(res);
  });

console.log("End!");
登录后复制
  • 承诺立即得到解决,值为“Promise!”。
  • JavaScript 将 showPromise(.then 回调)放入 微任务队列,因为 Promise 在解析后会进入微任务队列。

4。记录“结束!”

console.log("Start!");
登录后复制
  • 这行代码被添加到调用堆栈并立即执行。
  • 结果,“结束!” 被打印到控制台。

最终输出顺序:

setTimeout(function showTimeout() {
  console.log("Timeout!");
}, 0);
登录后复制

GIF供参考

Technical Interview Questions - Part  Event Loop
互动示例

结尾

本章并不太长,但我希望这些示例可以帮助您理解事件循环的工作原理。

我强烈建议尝试交互式页面来分析其他示例。在该页面上进行操作可以更轻松地理解正在运行的事件循环。

非常感谢大家对我之前帖子的喜爱!

下周见! ?

再见

Technical Interview Questions - Part  Event Loop

以上是技术面试问题 - 部分事件循环的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何创建和发布自己的JavaScript库? 如何创建和发布自己的JavaScript库? Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

如何在浏览器中优化JavaScript代码以进行性能? 如何在浏览器中优化JavaScript代码以进行性能? Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

如何使用浏览器开发人员工具有效调试JavaScript代码? 如何使用浏览器开发人员工具有效调试JavaScript代码? Mar 18, 2025 pm 03:16 PM

本文讨论了使用浏览器开发人员工具的有效JavaScript调试,专注于设置断点,使用控制台和分析性能。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何使用源地图调试缩小JavaScript代码? 如何使用源地图调试缩小JavaScript代码? Mar 18, 2025 pm 03:17 PM

本文说明了如何使用源地图通过将其映射回原始代码来调试JAVASCRIPT。它讨论了启用源地图,设置断点以及使用Chrome DevTools和WebPack之类的工具。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

console.log输出结果差异:两次调用为何不同? console.log输出结果差异:两次调用为何不同? Apr 04, 2025 pm 05:12 PM

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

See all articles