用动画的方式理解事件循环机制,没有搞懂的快来看看

简介: 事件循环是每个 JavaScript 开发人员都必须理解的知识点之一,但起初理解起来可能有点困难。 这篇开始,我会尝试通过低分辨率 gif 动画的方式解释它,进而来帮助你理解。

事件循环是每个 JavaScript 开发人员都必须理解的知识点之一,但起初理解起来可能有点困难。 这篇开始,我会尝试通过低分辨率 gif 动画的方式解释它,进而来帮助你理解。

首先,什么是事件循环,为什么要关心?

JavaScript 是单线程的:一次只能运行一个任务。 通常这没什么大不了的,但是现在假设正在运行一个需要 30 秒的任务。 在该任务期间,我们等待 30 秒,然后才能发生其他事情(JavaScript 默认在浏览器的主线程上运行, 所以整个 UI 都卡住了)😬 。如果这样的话,我想没有人想要一个缓慢、无响应的网站。

幸运的是,浏览器为我们提供了一些 JavaScript 引擎本身不提供的功能:Web API。 这包括 DOM API、setTimeout、HTTP 请求等。 这可以帮助我们创建一些异步的、非阻塞的行为🚀。

当我们调用一个函数时,它会被添加到调用堆栈中。 调用堆栈是 JS 引擎的一部分。 它是一个堆栈,这意味着它是先进后出的。 当一个函数返回一个值时,它会从堆栈中弹出:

在这里插入图片描述respond 函数返回一个 setTimeout 函数。 setTimeout 是由 Web API 提供给我们的:它让我们可以在不阻塞主线程的情况下延迟任务。 我们传递给 setTimeout 函数的回调函数() => { return 'Hey' } 被添加到 Web API 中。 与此同时,setTimeout 函数和 response 函数从堆栈中弹出,它们都返回了它们的值!

在这里插入图片描述

在 Web API 中,计时器的运行时间与我们传递给它的第二个参数一样长,即 1000 毫秒。 回调函数不会立即添加到调用堆栈中,而是传递给称为队列的东西。

在这里插入图片描述

这可能是一个令人困惑的部分:这并不意味着回调函数在 1000 毫秒后被添加到调用堆栈! 它只是在 1000 毫秒后被添加到队列中。 因为这是一个队列,函数的执行必须在队列中等待,直到轮到它!

如果调用堆栈是空的,那么如果所有先前调用的函数都返回了它们的值并且已经从堆栈中弹出,那么队列中的第一项将被添加到调用堆栈中。 在这种情况下,没有调用其他函数,这意味着当回调函数成为队列中的第一项时,调用堆栈为空。

在这里插入图片描述

回调函数被添加到调用堆栈,被调用,并返回一个值,然后从堆栈中弹出。

在这里插入图片描述

示例

如果我们运行以下代码,请尝试在输出在控制台看到的内容:

const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");

bar();
foo();
baz();

让我们看一下在浏览器中运行这段代码时发生了什么:

  1. 我们调用 bar函数。 bar 返回一个 setTimeout 函数。
  2. 我们传递给 setTimeout 的回调函数被添加到 Web API 中,然后setTimeout 函数和 bar 从调用堆栈中弹出。
  3. 计时器函数运行,同时 foo 函数被调用并打印 First。 foo 返回 undefined,baz 函数被调用,同时回调函数被添加到队列中。
  4. baz 打印 Third。 事件循环在 baz 返回后看到调用堆栈为空,之后回调被添加到调用堆栈中。
  5. 回调函数打印 Second

在这里插入图片描述

相关文章
|
8月前
|
安全 数据处理 C++
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
1619 3
|
2月前
|
存储 JavaScript 前端开发
事件循环的原理是什么
事件循环是一种编程机制,用于在单线程环境中处理多个任务。它通过维护一个任务队列,按顺序执行每个任务,并在任务之间切换,从而实现并发处理。在每个循环中,事件循环检查是否有新的任务加入队列,并执行就绪的任务。
|
5月前
|
前端开发 JavaScript
前端搞懂事件循环机制
【8月更文挑战第3天】前端搞懂事件循环机制
64 1
|
8月前
|
开发框架 JavaScript 前端开发
描述JavaScript事件循环机制,并举例说明在游戏循环更新中的应用。
JavaScript的事件循环机制是单线程处理异步操作的关键,由调用栈、事件队列和Web APIs构成。调用栈执行函数,遇到异步操作时交给Web APIs,完成后回调函数进入事件队列。当调用栈空时,事件循环取队列中的任务执行。在游戏开发中,事件循环驱动游戏循环更新,包括输入处理、逻辑更新和渲染。示例代码展示了如何模拟游戏循环,实际开发中常用框架提供更高级别的抽象。
45 1
带你读《深入浅出Dart》十六、事件循环和协程机制(5)
带你读《深入浅出Dart》十六、事件循环和协程机制(5)
带你读《深入浅出Dart》十六、事件循环和协程机制(4)
带你读《深入浅出Dart》十六、事件循环和协程机制(4)
102 0
|
Dart JavaScript 前端开发
带你读《深入浅出Dart》十六、事件循环和协程机制(1)
带你读《深入浅出Dart》十六、事件循环和协程机制(1)
131 0
带你读《深入浅出Dart》十六、事件循环和协程机制(3)
带你读《深入浅出Dart》十六、事件循环和协程机制(3)
104 0
带你读《深入浅出Dart》十六、事件循环和协程机制(2)
带你读《深入浅出Dart》十六、事件循环和协程机制(2)
|
设计模式 JavaScript 前端开发