事件循环,是每个 JavaScript 开发人员都必须要掌握的知识,开始学的时候,理解起来可能有点混乱。但我是一个视觉学习者,所以我想我会尝试通过低分辨率 gif 以视觉方式来解释它,以便帮助你更好的学习和理解事件循环。
首先,什么是事件循环,为什么要学习它?
JavaScript 是单线程的:一次只能运行一个任务。
通常你会觉得这没什么大不了的,但是,假设您正在运行一个需要 30 秒的任务,在该任务期间,我们等待 30 秒才能发生其他任何事情(JavaScript 默认在浏览器的主线程上运行,所以整个 UI 都卡住了),但是,我想没有人想要一个响应很慢有点卡顿的网站。
幸运的是,浏览器为我们提供了一些 JavaScript 引擎本身不提供的功能:Web API。这包括 DOM API、setTimeout、HTTP 请求等。这可以帮助我们创建一些异步的、非阻塞的行为。
当我们调用一个函数时,它会被添加到调用堆栈中。调用堆栈是 JS 引擎的一部分,这不是特定于浏览器的,它是一个堆栈,这意味着它是先进后出的(想想一堆煎饼)。当一个函数返回一个值时,它会从堆栈中弹出。
响应函数返回一个 setTimeout 函数。setTimeout 是由 Web API 提供给我们的:它让我们可以在不阻塞主线程的情况下延迟任务。我们传递给 setTimeout 函数的回调函数,箭头函数 () => { return 'Hey' } 被添加到 Web API。与此同时,setTimeout 函数和 respond 函数从堆栈中弹出,它们都返回了它们的值!
在 Web API 中,计时器的运行时间与我们传递给它的第二个参数一样长,即 1000 毫秒。回调不会立即添加到调用堆栈中,而是传递给称为队列的东西。
这可能是一个令人困惑的部分:这并不意味着回调函数在 1000 毫秒后被添加到调用堆栈(因此返回一个值)!它只是在 1000 毫秒后被添加到队列中。但这是一个队列,函数必须等待轮到它!
现在,我们一直在等待的部分......事件循环完成其唯一任务的时间:将队列与调用堆栈连接!如果调用堆栈是空的,那么,如果所有先前调用的函数都返回了它们的值,并且已经从堆栈中弹出,则队列中的第一项被添加到调用堆栈中。在这种情况下,没有调用其他函数,这意味着当回调函数成为队列中的第一项时,调用堆栈为空。
回调被添加到调用堆栈,被调用,并返回一个值,然后从堆栈中弹出。
阅读一篇文章很有趣,但你只有通过一遍又一遍地实际操作它才能完全理解学会。如果我们运行以下命令,请尝试找出记录到控制台的内容:
让我们快速看一下在浏览器中运行这段代码时发生了什么:
- 我们调用 bar。bar 返回一个 setTimeout 函数。
- 我们传递给 setTimeout 的回调被添加到 Web API,setTimeout 函数和 bar 从调用堆栈中弹出。
- 计时器运行,同时 foo 被调用并记录First。foo 返回(未定义),baz 被调用,回调被添加到队列中。
- baz日志Third。事件循环在 baz 返回后看到调用堆栈为空,之后回调被添加到调用堆栈中。
- 回调记录Second。
总结
以上就是我跟您分享关于事件循环的内容,希望这能让您对学习事件循环感到轻松有趣!如果它仍然看起来令人困惑,请不要担心,最重要的是了解某些错误/行为可能来自哪里,以便有效地从谷歌中搜索到正确的解决方案。
如果您觉得今天内容对您有用的话,请记得点赞我,关注我,并将它分享给您身边的朋友,也许能够帮助到他,最后,感谢阅读,祝编程愉快!