异步与事件
Nov 29, 2016
异步与事件队列的初步介绍.
理解同步和异步
同步: 当你在玩游戏时,肚子突然饿了,于是花了20分钟自己做了一个披萨.之后开始吃然后继续玩游戏.
异步: 当你在玩游戏时,肚子突然饿了,于是拿起手机点了一份20元的披萨.之后开始吃然后继续玩游戏.
首先明确,你的主要目的是完成两件事,玩游戏,吃披萨.
在同步的事件中,你用了20分钟玩游戏的时间自己做了一个披萨,吃到了披萨.
在异步的事件中,你花费了20元买了一个披萨,吃到了披萨.
JavaScript是单线程,同步的
单线程(single-threaded): 一次只执行一条指令.线程是CPU顺序执行指令的一个调度单位.
JS引擎中的行为是单线程,同步的,但在浏览器中,不仅仅只有JS引擎存在,还存在其他部分(如渲染引擎),JS引擎和外部的交流是异步的.
事件队列
JS引擎工作时除了有执行栈,还存在一个事件队列(Event Queue),如果用户触发了JS引擎能够处理的事件,这个事件就会被放置于事件队列中等待JS引擎处理,当执行栈为空时,JS引擎开始处理队列中的事件.只有执行栈空时才会开始处理.JS引擎检查事件队列的持续行为称为 Event Loop .
所以异步指的是浏览器异步将事件置于事件队列,是JS引擎外的行为,代码依旧是一行一行执行.
1 | function waitThreeSeconds() { |
console.log('finished execution');
这段代码结束执行之后,执行栈才空,开始处理点击事件.
Ps: js文件的位置
app.js
必须放在body的关闭标签之前,如果放在<head>
标签之内,三秒之内无论点击多少次,click事件都不会执行.
1 |
|
原因:
浏览器加载含有<script>
标签的网页过程:
- 获取HTML
- 开始解析HTML
- 解析器解析到连接外部JS文件的
<script>
标签 - 浏览器请求外部JS文件,同时暂停解析HTML
- 一段时间后JS文件加载完成然后成功执行
- 之后解析器开始解析余下部分的HTML
因此如果script在head标签内,表示浏览器的页面还没有渲染,无论如何点击,都获取不到这一事件.