(上一篇只有复习,没有带到题目,所以这篇会解释两个问题,答案可以直接看结论~)
在上一篇文章 7. 解释 Event Loop ( 上 ) --- Call Stack有提到,非同步的程序设计是为了解决单执行绪在事件的处理上,没有效率的问题。
而这篇文章的主题 —— Event Loop,就是用来控制在JS里同步与非同步事件的运行:
(以 Google Chrome的V8引擎为例。 )
解释一下这张图:
JavaScript Engine本身涵盖两个Components:
许多我们在浏览器使用的API(e.g. DOM, AJAX, Timeout...),并非来自JS引擎,而是由浏览器的 Web APIs 提供。
所有被放进Async Function里,作为参数的function,被称作"callback",这些callback被依序放在 callback queue 等待执行。(负责排序非同步执行函式)
→ 所有执行环境的共通点,就是都有一个叫"event loop"的内建机制。
它会随着时间执行上述被分类的任务,并在每次执行时调用JS引擎。
( ↑ 全文重点
+++++++++++++++++++++++++
整理一下逻辑关系:
+++++++++++++++++++++++++
我们已经知道DOM, AJAX, Timeout...都是由Web APIs提供的API,而当我们使用这些API进行非同步的呼叫(callback function),
Event Loop 会将 callback function 放进 Callback Queue (伫列)。
( 我自己在解释的时候偏好讲Callback Queue,但因为题目写Task Queue,所以下面结论是讲Task Queue。)
伫列也是资料结构的一种,特色是先进先出(First-In-First-Out, FIFO)。
假设物件依照a, b, c的顺序被放入,越早放入的会越早取出,所以取出的顺序也是a, b, c。
A JavaScript runtime uses a message queue, which is a list of messages to be processed. Each message has an associated function which gets called in order to handle the message.
→ 直到Call Stack被清空,Event Loop会将Callback Queue里最早纪录的讯息(message)放入Call Stack,直到Callback Queue里的message也被清除完成。
这里可以执行一个例子:
console.log('start');
setTimeout(function callback() {
console.log('callback is here');
}, 3000);
console.log('end');
setTimeout()的执行方式
setTimeout()并不会直接将callback交给event Loop,他会先建造自己的计时器(timer),直到计时结束,才将将callback放进callback queue。
→ 因此,上面例子的3000
不是指3秒後就会执行程序,而是3秒後才会被放进伫列。
start
end
callback is here // 3秒後出现
然後上面的执行顺序是这样的: gif和图档(这次图片放进来反而有点乱,所以和gif的连结放在一起。)
console.log('start')
放进call stack;执行console.log('start')
。console.log('end')
放进call stack;执行console.log('end')
。callback()
进入【Callback Queue】callback()
放进call stack;执行callback()
。【In Call stack】 | 【In web api】 | 【In Callback Queue】 | |
---|---|---|---|
1 | console.log('start') 放进call stack;执行console.log('start') 。 |
--- | --- |
2 | --- | setTimeout(callback() )建立timer,等3秒... |
↘ |
3 | console.log('end') 放进call stack;执行console.log('end') 。 |
--- | ↓ |
4 | --- | --- | 3秒结束,callback() 进入【Callback Queue】 |
5 | callback() 放进call stack;执行callback() 。 |
← | ← |
解释Event Loop的运作?
因为JS的执行是单执行绪的,在处理同步事件时,会将函式放在Call Stack执行。
如果是请求资料或滑鼠点击之类的非同步事件,则会将事件交给浏览器提供的Web APIs,在解析完成後,放到Task Queue,等待Call Stack里的函式执行完毕後,再继续将Task Queue里的函式依序放入Call Stack,并完成剩余函式。
Call Stack和Task Queue的差异?
Call Stack用於同步事件的函式执行,Task Queue用於非同步事件的函式执行,而Call Stack里的工作会先被执行完毕。
Call Stack的结构是後进先出(LIFO),越早放进Call Stack的函式会越晚被执行;而Task Queue则是先进先出(FIFO),被放进Task Queue的函式,会依照放入顺序执行。
【如内文有误还请不吝指教>< 谢谢阅览至此的各位:D】
参考资料:
-----正文结束-----
我自己是会听歌听到舍不得去睡觉的人,所以事情做不完的时候,音乐放出来我就会乖乖做下去了。
前阵子才把《La La Land》补完,但在看电影之前就很喜欢《City Of Stars》这首歌。
前言 因为资料库基本上可以分成 SQL 跟 NoSQL 两大类,昨天讲完 SQL injection...
承上一篇,公开申购公告的纲页页面如下 依照我们会需要的栏位,我们的 model 如下 // // S...
看到有永丰金融 API 可以玩,於是就下定决心报名了~ 报名非常简单,填一下资料马上就在 E-MAI...
USing Lombok in IDEA ...
React 运作原理 在原生的 JavaScript 里,我们会操作 DOM 来修改网页程序码,但这...