Async JavaScript Visualized With Ease

从动图轻松入门非同步 JavaScript(第一章)

了解非同步 JavaScript 背后如何运作

浏览器执行环境中的 JavaScript 是单线程的,也就是一次只能执行一件事,通常这不是问题,但假设目前有一个超~~繁琐的事件要处理 30 秒,或是去索取一个未知要多少时间的外部资源,这样其他事情就都被搁置在后,让用户等待。

这是非常大的问题,但解决方法也非常简单:「不要呆呆站在那里等!」。

假设订了外送,会乖乖地等到外送员到家后吃饭,还是先做其他事情呢?想必是后者,那么同样的道理,各种不同的执行环境(runtime) 也提供了 JavaScript 自身并不存在的功能来处理非同步的操作,比如在浏览器中有: Web API,可以轻松创造非同步、避免事件阻塞的网页。

图解专有名词

Call Stack:处理事情,就像在吃松饼

回到 JavaScript 引擎本身,当调用一个函数时,函数会被加入到一个叫做:「Call Stack」的 STACK (堆栈🔗)之中,想象成吃松饼一样,松饼(函数)由最上方加入然后再由上方开始吃掉(处理),代码由上而下执行将函数推入执行堆栈中,当被执行完就会离开。

Web API:浏览器提供的非同步好帮手

而处理非同步事件常遇到的有:fetchsetTimeoutaddEventListener,这些都是由 Web API 所提供的方法,使用这些方法传入的回调函数将会交由 Web API 处理,因此 Call Stack 才能迅速被清空,处理下一个事件,不阻塞 JavaScript 的执行。

Callback Queue:等待入场的队伍

Web API 的事项处理完成后并不会马上返回 Call Stack 被执行,而是会被放入 Callback Queue 中等待。这也造成了像是 setTimeoutsetInterval 并不“准确”的如同描述的时间内被执行,而是单纯在描述时间后会被加入 Callback Queue。

Event Loop:连接整个流程

那么 Callback Queue 中的事项要如何被执行呢? 就轮到 Event Loop 出场的时候了,它只有也仅有一个功能:“连接 Callback Queue 与 Call Stack”。具体来说,当 Call Stack 是空的,第一件 Callback Queue 的事项就会被放入 Call Stack 中,

结语

希望经过简单的动图,可以更直观快速的了解到非同步 JavaScript 背后究竟发生了什么事。

参考资料