所?单线E?Q就是指一ơ只能完成一件Q务。如果有多个dQ就必须排队Q前面一个Q务完成,再执行后面一个Q务,以此cL?/p>
q种模式的好处是实现h比较单,执行环境相对单纯Q坏处是只要有一个Q务耗时很长Q后面的d都必L队等着Q会(x)拖g整个E序的执行。常见的览器无响应Q假死)Q往往是因ؓ(f)某一DJavascript代码长时间运行(比如d@环)Q导致整个页面卡在这个地方,其他d无法执行?/p>
Z解决q个问题QJavascript语言Q务的执行模式分成两种Q同步(SynchronousQ和异步QAsynchronousQ?/p>
"同步模式"是上一D늚模式Q后一个Q务等待前一个Q务结束,然后再执行,E序的执行顺序与d的排列顺序是一致的、同步的Q?异步模式"则完全不同,每一个Q务有一个或多个回调函数QcallbackQ,前一个Q务结束后Q不是执行后一个Q务,而是执行回调函数Q后一个Q务则是不{前一个Q务结束就执行Q所以程序的执行序与Q务的排列序是不一致的、异步的?/p>
"异步模式"非常重要。在览器端Q耗时很长的操作都应该异步执行Q避免浏览器失去响应Q最好的例子是Ajax操作。在服务器端Q?异步模式"甚至是唯一的模式,因ؓ(f)执行环境是单U程的,如果允许同步执行所有httphQ服务器性能?x)急剧下降Q很快就?x)失d应?/p>
本文ȝ?异步模式"~程?U方法,理解它们可以让你写出l构更合理、性能更出艌Ӏ维护更方便的JavascriptE序?/p>
一、回调函?/strong>
q是异步~程最基本的方法?/p>
假定有两个函数f1和f2Q后者等待前者的执行l果?/p>
f1(); f2();
如果f1是一个很耗时的Q务,可以考虑改写f1Q把f2写成f1的回调函数?/p>
function f1(callback){ setTimeout(function () { // f1的Q务代?/span> callback(); }, 1000); }
执行代码变成下面这P(x)
f1(f2);
采用q种方式Q我们把同步操作变成了异步操作,f1不会(x)堵塞E序q行Q相当于先执行程序的主要逻辑Q将耗时的操作推q执行?/p>
回调函数的优Ҏ(gu)单、容易理解和部vQ缺Ҏ(gu)不利于代码的阅读和维护,E序的流E会(x)很乱,而且每个d只能指定一个回调函数?/p>
二、事件监?/strong>
另一U思\是采用事仉动模式。Q务的执行不取决于代码的顺序,而取决于某个事g是否发生?/p>
q是以f1和f2Z。首先,为f1l定一个事Ӟq里采用的jQuery?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">写法Q?/p>
f1.on('done'Qf2);
上面q行代码的意思是Q当f1发生done事gQ就执行f2。然后,对f1q行改写Q?/p>
function f1(){ setTimeout(function () { // f1的Q务代?/span> f1.trigger('done'); }, 1000); }
f1.trigger('done')表示Q执行完成后Q立卌发done事gQ从而开始执行f2?/p>
q种Ҏ(gu)的优Ҏ(gu)比较Ҏ(gu)理解Q可以绑定多个事Ӟ每个事g可以指定多个回调函数。缺Ҏ(gu)整个E序都要变成事g驱动型,q行程?x)变得很不清晰?/p>
三、发?订阅
上一节的"事g"Q完全可以理解成"信号"?/p>
我们假定Q存在一?信号中心"Q某个Q务执行完成,向信号中心"发布"QpublishQ一个信P其他d可以向信号中?订阅"QsubscribeQ这个信P从而知道什么时候自己可以开始执行。这叫?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">"发布/订阅模式"Qpublish-subscribe patternQ,又称"观察者模?Qobserver patternQ?/p>
q个模式有多U?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">实现Q下面采用的是Ben Alman?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">Tiny Pub/SubQ这是jQuery的一个插件?/p>
首先Qf2?信号中心"jQuery订阅"done"信号?/p>
jQuery.subscribe("done", f2);
然后Qf1q行如下改写Q?/p>
function f1(){ setTimeout(function () { // f1的Q务代?/span> jQuery.publish("done"); }, 1000); }
jQuery.publish("done")的意思是Qf1执行完成后,?信号中心"jQuery发布"done"信号Q从而引发f2的执行?/p>
此外Qf2完成执行后,也可以取消订阅(unsubscribeQ?/p>
jQuery.unsubscribe("done", f2);
q种Ҏ(gu)的性质?事g监听"cMQ但是明显优于后者。因为我们可以通过查看"消息中心"Q了解存在多信受每个信h多少订阅者,从而监控程序的q行?/p>
四、Promises对象
Promises对象是CommonJS工作l提出的一U规范,目的是ؓ(f)异步~程提供l一接口?/p>
单说Q它的思想是,每一个异步Q务返回一个Promise对象Q该对象有一个thenҎ(gu)Q允许指定回调函数。比如,f1的回调函数f2Q可以写成:(x)
f1().then(f2);
f1要进行如下改写(q里使用的是jQuery?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">实现Q:(x)
function f1(){ var dfd = $.Deferred(); setTimeout(function () { // f1的Q务代?/span> dfd.resolve(); }, 500); return dfd.promise; }
q样写的优点在于Q回调函数变成了铑ּ写法Q程序的程可以看得很清楚,而且有一整套?a target="_blank" style="margin: 0px; padding: 0px; color: #1a64a2; text-decoration: none; ">配套Ҏ(gu)Q可以实现许多强大的功能?/p>
比如Q指定多个回调函敎ͼ(x)
f1().then(f2).then(f3);
再比如,指定发生错误时的回调函数Q?/p>
f1().then(f2).fail(f3);
而且Q它q有一个前面三U方法都没有的好处:(x)如果一个Q务已l完成,再添加回调函敎ͼ该回调函C(x)立即执行。所以,你不用担心是否错q了某个事g或信受这U方法的~点是~写和理解,都相Ҏ(gu)较难?/p>
五、参考链?/strong>
* Asynchronous JS: Callbacks, Listeners, Control Flow Libs and Promises
el表达式一般不直接?=判断是否相等 != > < >= <=之类的表CZ{于 大于 于 大于{于 于{于,而是使用字母表示的表辑ּ,他们的表C如下:(x)
== eq {于
!= ne 不等?br /> > gt 大于
< lt 于
>= ge 大于{于
<= le 于{于
字符串比较:(x)
不需要双引号“”
user.name eq '001'
user.name eq Lily
Input表示Form表单中的一U输入对象,其又随Typecd的不同而分文本输入框,密码输入框,单?复选框Q提?重置按钮{,下面一一介绍?
1Qtype=text
输入cd是textQ这是我们见的最多也是用最多的Q比如登陆输入用户名Q注册输入电(sh)话号码,?sh)子邮gQ家庭住址{等。当然这也是Input的默认类型?
参数nameQ同h表示的该文本输入框名U?
参数sizeQ输入框的长度大?
参数maxlengthQ输入框中允许输入字W的最大数?
参数valueQ输入框中的默认?
Ҏ(gu)参数readonlyQ表C框中只能昄Q不能添加修攏V?/p>
<form>
your name:
<input type="text" name="yourname" size="30" maxlength="20" value="输入框的长度?0Q允许最大字W数?0"><br>
<input type="text" name="yourname" size="30" maxlength="20" readonly value="你只能读不能修改">
</form>
2Qtype=password
不用我说Q一看就明白的密码输入框Q最大的区别是当在此输入框输入信息时显CZؓ(f)保密字符?
参数?#8220;type=text”相类伹{?
<form>
your password:
<input type="password" name="yourpwd" size="20" maxlength="15" value="123456">密码长度于15
</form>
3Qtype=file
当你在BBS上传囄Q在EMAIL中上传附件时一定少不了的东西:(x)Q?
提供了一个文件目录输入的q_Q参数有nameQsize?
<form>
your file:
<input type="file" name="yourfile" size="30">
</form>
4Qtype=hidden
非常值得注意的一个,通常UCؓ(f)隐藏域:(x)如果一个非帔R要的信息需要被提交C一,但又不能或者无法明C的时候?
一句话Q你在页面中是看不到hidden在哪里。最有用的是hidden的倹{?/p>
<form name="form1">
your hidden info here:
<input type="hidden" name="yourhiddeninfo" value="cnbruce.com">
</form>
<script>
alert("隐藏域的值是 "+document.form1.yourhiddeninfo.value)
</script>
5Qtype=button
标准的一windows风格的按钮,当然要让按钮跌{到某个页面上q需要加入写JavaS
<form name="form1">
your button:
<input type="button" name="yourhiddeninfo" value="GoQGoQGoQ? on
</form>
6Qtype=checkbox
多选框Q常见于注册旉择爱好、性格、等信息。参数有name,value?qing)特别参数checkedQ表C默认选择Q?
其实最重要的还是value|提交到处理页的也是value。(附:(x)name值可以不一P但不推荐。)
<form name="form1">
a:<input type="checkbox" name="checkit" value="a" checked><br>
b:<input type="checkbox" name="checkit" value="b"><br>
c:<input type="checkbox" name="checkit" value="c"><br>
</form>
name值可以不一P但不推荐<br>
<form name="form1">
a:<input type="checkbox" name="checkit1" value="a" checked><br>
b:<input type="checkbox" name="checkit2" value="b"><br>
c:<input type="checkbox" name="checkit3" value="c"><br>
</form>
7Qtype=radio
卛_选框Q出现在多选一的页面设定中。参数同hname,value?qing)特别参数checked.
不同于checkbox的是Qnameg定要相同Q否则就不能多选一。当然提交到处理늚也还是value倹{?/p>
<form name="form1">
a:<input type="radio" name="checkit" value="a" checked><br>
b:<input type="radio" name="checkit" value="b"><br>
c:<input type="radio" name="checkit" value="c"><br>
</form>
下面是nameg同的一个例子,׃能实现多选一的效果了<br>
<form name="form1">
a:<input type="radio" name="checkit1" value="a" checked><br>
b:<input type="radio" name="checkit2" value="b"><br>
c:<input type="radio" name="checkit3" value="c"><br>
</form>
8Qtype=image
比较另类的一个,自己看看效果吧,可以作ؓ(f)提交式图?/p>
<form name="form1" act
your Imgsubmit:
<input type="image" src="../blog/images/face4.gif">
</form>
<form name="form1" act
9Qtype=submit and type=reset
分别?#8220;提交”?#8220;重置”两按?
submit主要功能是将Form中所有内容进行提交act
<input type="text" name="yourname">
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>