• 动态图演示js事件循环完整过程
  • 发布于 2个月前
  • 122 热度
    0 评论
事件循环。这是每一个JavaScript开发人员都必须以这样或那样的方式处理的事件之一,刚开始理解起来可能有点混乱。作为一个视觉学习者,我想我应该试着通过低分辨率的动图来帮助你。

但首先,什么是事件循环?为什么要关心这个问题?

JavaScript是单线程:一次只能运行一个任务。通常这没什么大不了的,但现在想象一下你正在运行一个需要30秒的任务.。在这个任务中,我们要等待30秒才能有其他的事情发生(JavaScript默认运行在浏览器的主线程上,所以整个UI都卡住了)。幸运的是,浏览器为我们提供了JavaScript引擎本身不提供的一些特性:Web API。这包括DOM API、HTTP、settimeout请求等。这可以帮助我们创建一些异步、非阻塞行为等等。


当我们调用一个函数时,它会被添加到调用堆栈中。调用堆栈是JS引擎的一部分,这与浏览器无关。这是一整个堆栈,意味着它是第一个进去,最后一个出来(把它们想象成一堆煎饼)。当一个函数返回一个值时,它会从堆栈中弹出。

响应函数返回一个setTimeout函数。setTimeout由Web API提供给我们:它让我们在不阻止主线程的情况下延迟任务。我们传递给setTimeout函数的回调函数,箭头函数()=> { return 'Hey' }被添加到Web API中。与此同时,setTimeout函数和响应函数从堆栈中弹出,它们都返回了它们的值。   

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

这可能是一个令人困惑的部分:这并不意味着回调函数在1000ms后被添加到callstack(因此返回一个值)它只需在1000ms后添加到队列中。但这是一个队列,该功能必须要等待轮到它才行,!


现在,这就是我们一直在等待的部分......事件循环是时候完成其唯一的任务了:将队列与调用堆栈连接!如果调用堆栈是空的,那么如果所有以前调用的函数都返回其值并已从堆栈中弹出,则队列中的第一个项目将添加到调用堆栈中。在这种情况下,没有调用其他函数,这意味着当回调函数是队列中的第一个项目时,调用堆栈是空的。   

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

这篇文章读起来很有趣,但只有通过一遍又一遍地处理它,你才会完全适应它。如果我们运行以下操作,请尝试弄清楚什么会登录到控制台:

让我们快速看看当我们在浏览器中运行此代码时发生了什么:

1.我们调用bar。bar返回一个setTimeout函数。
2.我们传递给setTimeout的回调被添加到Web API中,thestTimeout函数和bar从调用堆栈中弹出。
3.计时器运行,同时调用foo并First记录。foo返回(未定义),调用baz,回调添加到队列中。
4.baz日志Third。事件循环在返回baz后看到调用堆栈是空的,之后回调被添加到调用堆栈中。
5.回调记录Second。
用户评论