2

单线程

Js语言的执行环境是“单线程”。所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
Java是多线程编程语言,本人并没有接触过多线程的编程语言,在此就略过。

同步与异步

为了同步模式下的阻塞问题,Js语言将任务的执行模式分成两种:同步和异步。
同步模式,即上面所说的模式,任务按排列顺序执行;异步模式,其实就是延迟处理。在和HTML交互的过程中,会需要一些IO操作(典型的就是Ajax请求,脚本文件加载),如果这些操作是同步的,就会阻塞其它操作,用户的体验就是页面失去了响应。异步是通过异步函数实现的,如setTimeout()。

Javascript事件驱动

下面看一个例子。

var start = new Date();
setTimeout(function() {
var current = new Date();
var dvalue = current - start;
alert(dvalue + 'ms');
},500);
while(new Date() - start < 1000) {

}

我在google浏览器里,运行的结果是1002ms,因为setTimeout和setInterval的计时精度问题,不同的浏览器里得到的数值可能稍微有出入。但是这个数值肯定大于1000ms。
在这个例子里,js按顺序往下执行时,遇到setTimeout()函数,setTimeout()函数直接返回,里面的回调函数被放入到事件队列里。js接着往下执行while循环。当时间差>=1000时,跳出循环,执行完毕。此时js才会去处理队列里的事件。如果有适合“触发”(就像1000ms之前设定好的延迟500ms的延时事件)的事件,则调用该事件的处理函数。事件处理器返回后,我们又回到队列处。
在这里,我们要详细介绍下Javascript事件驱动机制。事件驱动一般通过事件循环(event loop)和事件队列(event queue)来实现的。假定浏览器中有一个专门用于事件调度的实例(该实例可以是一个线程,我们可以称之为事件分发线程event dispatch thread),该实例的工作就是一个不结束的循环,事件分发线程从事件队列中取出事件,调度事件的排队顺序,并不执行代码,注意回调函数是在Javascript的主线程中执行的,而非事件分发线程中,以保证事件处理不会发生阻塞。
在这里要注意“触发”和“执行”的区别。触发只是插入队列,执行才是真正的执行代码。这里的分发线程和主线程应该就是对应触发和执行这两个概念。
通过事件驱动机制,我们可以想象Javascript的编程模型就是响应一系列的事件,执行对应的回调函数。很多UI框架都采用这样的模型(例如Java Swing)。
暂时记录到这里,后续补充。

参考链接:
http://web.jobbole.com/82291/
http://www.ruanyifeng.com/blo...


zilan
307 声望6 粉丝

引用和评论

0 条评论