用披萨店类比来可视化 JavaScript 事件循环
假设有一家披萨店。
目前,一位顾客会向我们提出两种类型的订单——一种是比较复杂的订单,要求披萨上要有橄榄(1)、奶酪馅(2)和大饼底(3)。
另一种则是简单的订单,只需要蛋黄酱(a)和蒜蓉面包(b)。
厨师接到订单后开始制作第一张披萨,他先取一个大饼底(3),放入馅料(2),然后撒上橄榄(1)。 这位厨师还要制作蒜蓉面包。这时,经理突然发现餐厅的蛋黄酱用完了。经理把“采购蛋黄酱”的任务添加到工作表中,并派唯一空闲的跑腿小弟去买。
理论上讲,如果所有订单一起下单一起送,顾客就得等到跑腿的去五个街区外的超市买蛋黄酱,再交给厨师才能完成订单。但这里是餐厅,顾客没必要一次性收到所有菜品。
厨师决定继续制作披萨,烤好后送给顾客。
这时,跑腿的送餐员带着蛋黄酱来了,厨师拿了一些蒜蓉面包(b),在上面涂上蛋黄酱(a),然后交给顾客。
我们在这里学到了哪些关于JavaScript的知识?
- 顾客的订单(制作披萨 + 制作蒜蓉面包)是JavaScript 代码中的函数。
- 订单详情指的是如何定制披萨和面包,可以将其视为在 `make Pizza` 函数内部调用的函数——订单顺序从上到下依次为:配料、馅料和尺寸。这些详情本质上是调用栈的表示,调用栈会按相反的顺序执行所有这些事件。
- 餐厅缺货——这是一个触发事件,它调用了一个异步函数,该函数负责从超市取货。由于餐厅不需要一次性发送所有订单,因此他们会按照调用栈中任务的逆序执行这些任务,正如前面故事中所述。
- 这里的经理是事件记录员——他的工作是按时间顺序记录所有发生的事故(事件)。
- 跑腿小弟就是事件队列,也就是说,如果他已经被要求去取某物,而现在又请求取一个新的物品,那么这个新物品就必须等到跑腿小弟取回旧物品之后才能被取走。
- 厨师就是事件循环,它会不断地下达订单(执行所有功能)。
- 餐厅就像一个浏览器,无需等到所有内容加载完毕才停止运行,也无需等待其他操作完成才能继续执行。(无需将所有订单一起上菜)
本质上,事件循环会检查调用栈是否为空,如果为空,则检查事件队列。如果队列中有待处理的事件,则将其添加到调用栈并执行。事件循环会持续运行,直到其工作周期结束(浏览器内容加载完毕/浏览器关闭)。事件表会跟踪所有已触发的事件,并将它们发送到事件队列以待执行。
这是我对事件循环的解释,如果你觉得这个比喻有趣,请告诉我!
文章来源:https://dev.to/presto412/visualising-the-javascript-event-loop-with-a-pizza-restaurant-analogy-47a8