最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JavaScript中异步、单线程和队列实例介绍
时间:2014-02-10 编辑:简简单单 来源:一聚教程网
这是我第一次明白 JavaScript 的异步、单线程、队列这几个概念,感谢 Async JavaScript 一书。
异步计时函数
首先从异步计时函数 setTimeout 说起:
代码如下 | 复制代码 |
var begin = new Date();//代码开始 |
在 firefox 下,按 Shift + F4 调出代码片段速记器,将以上代码拷入,然后 Ctrl - R 运行。
我的某次数值是 2019。
这个数值让我大吃一惊,不是说好1秒后弹对话框的吗?
如果我们是在多线程程序语言下,那我们的期望是对的。但 JavaScript 是单线程,这就与我们的期望有出入。
单线程是什么意思?
JavaScript 从 var begin = new Date(); 执行起,然后解析 setTimout 函数。setTimout 一段代码表示,嘿,请把我加入队列里,1秒后运行。然后回调函数拿好号,到一边排队等候。
JavaScript 继续运行下一句 – 在这个例子中是 while 循环。这个循环要持续2秒。这期间,回调函数很安静,它不至于盯着时间,过去1秒时就插话,喂,1秒过去了,该我运行。
这就是单线程设计下的 JavaScript。队列里的回调函数不会主动发问,它只是被动等待。等 JavaScript 忙完最后一句代码,JavaScript 虚拟机就会朝队列喊话:下一个。
这时,我们的 alert 终于可以运行了 – 但时间已经过去 2019 毫秒。
异步 I/O 函数
现代常用的 Ajax 操作属于异步 I/O 类型,比如 GET、POST。
代码如下 | 复制代码 |
$.get('http://www.111com.net/',function(data){//因为 JavaScript 的同源策略,本地执行本语句其实会失败,仅做示例 |
JavaScript 在执行到 get 语句时,发起 HTTP 请求,要求返回 http://www.111com.net/ 页面,并且定义一个回调函数,将回调加入事件队列,以便 HTTP 响应成功时接收数据,然后 JavaScript 继续执行下一句,即 while,因为 while 条件一直为真,所以程序将永远运行下去,此前定义的回调函数一直在排队,页面呈假死状态。
当然,这个例子有点极端,举一个轻松点的,本地服务器上架设的例子:
代码如下 | 复制代码 |
$.get('index.html',function(data){ |
代码执行到 ‘hey Chen’ 一句,浏览器弹出对话框窗口。
且慢关掉对话框窗口,打开 Google Chrome 开发者工具查看 Network 选项卡,get 语句的 Status Text 字段正处在 Pending 状态中。chrome 开发者工具帮助上并没有说明这个词的意思,但我们可以借助 WireShark 或 Fiddler2 检查 HTTP 请求的状况:
上图中可以看到,请求 – 响应过程是成功的,只是 get 定义的回调未能执行,所以 Chrome 下显示成 Pending 状态。现在我们按下对话框窗口的确定按钮,又或关掉对话框,回调函数就执行了。
以上是 Google Chrome 30.0.1599.114 版本下的情况,即 alert 方法会阻止事件循环,导致回调无法接收数据。
Firefox 24 下的情况略有不同,示例3中的 alert 并不能阻止事件循环,两个 ajax 请求全部执行并且回调也执行了,这样页面上会有三个弹出对话框。
WireShark 抓取的 Firefox 下 HTTP 数据如图:
wireshark log firefox http
当然,浏览器的处理方法不同这种事情实在不值得我大惊小怪,毕竟,我是从 IE6 混战里活过来的
相关文章
- JavaScript实现二分查找实例代码 04-24
- JavaScript实现的鼠标响应颜色渐变效果完整实例 04-17
- JavaScript实现图像模糊化的方法实例 02-04
- JavaScript中localStorage对象存储方式实例分析 01-14
- Javascript高性能之递归,迭代,查表法详解及实例 01-09
- javascript中定时器的实例代码 12-20