AOP in JavaScript
作者: 出处: 更新时间:2007-10-25 责任编辑:
 
 

AOP 是 Dojo 宣传中一个重要的特性, Alex 那个著名的 PDF : FP and AOP in JavaScript 介绍了Dojo的AOP编程。
Dojo 的 AOP 实现被集成在Dojo的事件处理框架(Dojo Event System)中,可以先看看本站的Wiki。 或者 zkjbeyond 兄分享的 dojo的事件机制序列文章。

同样的,根据 zkjbeyond 的研究,Yahoo! YUI 的事件处理机制也可以略嫌蹩脚的模拟AOP。

其实很早就已经有人探索AOP在JavaScript里的实现了,AOP Fun with JavaScript是我能找到的最早的文献。

DOTVOID 又将其完善,从 Aspect Oriented Programming and javascript 一文中可以看到他的实现和代码范例。该文的留言中有人建议 Dotvoid 将其实现集成到 Prototype 中去,不过 Dotvoid 说他没有时间这么做。

不久前,beppu 在他的博客上 beppu.lbox.org 分享了他的实现。最开始叫 The Decorator Pattern for JavaScript,用一个名为 actsAsDecorator() 的函数使得参数对象拥有了设置装饰器的能力。

几天后,新版本更名为 actsAsAspect(),以更为简洁的代码出现,并增加 around 通知(advice)类型的支持。

尽管还不是一个成熟的版本,但他的代码和详细的使用说明能够帮助我们理解所谓 AOP 用JavaScript实现的过程。同时他的实现得到了 Scriptaculous 的作者 Thomas Fuchs 的鼓励。也许有一天,AOP的支持也能集成到Prototype 中去。

目前确实还是Dojo 的AOP实现强大和优雅得多。如果想弄明白Dojo的实现原理,除了痛苦的阅读源码,强烈推荐看看这篇文章:Aspects in JavaScript,或许能让你茅塞顿开。

总之,服务器端开发的那一套理论或技术,正慢慢的被尝试迁移在客户端模拟实现。动态脚本语言与生具来的灵活性让其实现AOP相对容易很多。我想对于客户端编程开发人员来说,叫装饰器也好,叫AOP也罢,重要的不光是知道如何实现,而是要理解和正确规划AOP的核心——职责与业务对象分离。如同体会Web页面开发的表现/内容/行为分离的思想一样。

其实让我们回头来看著名的 Behaviour 脚本,它将CSS 选择器与事件处理器连接了起来。如果将一个个的事件处理函数当做通知(advice),而将 CSS 选择器视为切入点(join-point), 这是否也就是AOP了呢?

6个评论 (评论者 benny, dogstar, Arrix, realazy, zkjbeyond, fdcn) | 发表评论

Sleep in JavaScript

除了Narrative JS,jwacs(Javascript With Advanced Continuation Support) 也致力于通过扩展JavaScript语法来避免编写让人头痛的异步调用的回调函数。用jwacs 实现的sleep,代码是这样:

function sleep(msec) {
var k = function_continuation;
setTimeout(function() { resume k <- mesc; }, msec);
suspend;
}这个语法更吓人了,而且还是java里不被推荐使用的线程方法名。坦白说我倾向于 Narrative JS。

同Narrative JS一样,jwacs也需要预编译,预编译器是用 LISP 语言编写。目前也是 Alpha 的版本。两者的更多介绍和比较可以参阅 SitePoint 上的新文章: Eliminating async Javascript callbacks by preprocessing

编写复杂的JavaScript脚本时,有时会有需求希望脚本能停滞指定的一段时间,类似于 java 中的 Thread.sleep 或者 sh 脚本中的 sleep 命令所实现的效果。

众所周知,JavaScript 并没有提供类似于 Java 的线程控制的功能, 虽然有 setTimeout 和 setInterval 两个方法可以做一些定时执行控制,但并不能满足所有的要求。一直以来,都有很多人问如何在JavaScript中实现 sleep/pause/wait ,也确实有些很蹩脚的解决方案:

最简单也最糟糕的方法就是写一个循环,代码可能如下:

function sleep(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}如上的代码其实并没有让脚本解释器sleep下来,而且有让CPU迅速上到高负荷的附作用。浏览器甚至会在该段时间内处于假死状态。

其二有聪明人利用IE特殊的对话框实现来曲径通幽,代码可能如下:

function sleep(timeout) {
window.showModalDialog("javascript:document.writeln('<script>window.setTimeout(function () { window.close(); }, " + timeout + ");<\/script>');");
}window.alert("before sleep ...");
sleep(2000);
window.alert("after sleep ...");缺点不用多说,只有IE支持(IE7因为安全限制也而不能达到目的)。

除上之外,还有利用Applet或者调用Windows Script Host的WScript.Sleep()等等鬼点子,这些都是万不得已的权宜之计。

终于有了更聪明的人,开发出了也许是最佳的方案,先看代码:

function sleep(millis) {
var notifier = NjsRuntime.createNotifier();
setTimeout(notifier, millis);
notifier.wait->();
}没错,看到 ->() 这样的语法,就象刚看到Prototype的 $() 函数一样让我惊为天人。不过直接在浏览器中这段脚本是会报告语法错误的。实际上它们需要经过预编译成客户端浏览器认可的JavaScript。编译后的脚本如下:

function sleep(millis){var njf1 = njen(this,arguments,"millis");nj:while(1) {try{switch(njf1.cp) { case 0:njf1._notifier=NjsRuntime.createNotifier();setTimeout(njf1._notifier,njf1._millis);njf1.cp = 1;njf1._notifier.wait(njf1);return;case 1:break nj; }} catch(ex) { if(!njf1.except(ex,1)) return; }} njf1.pf();}我看不懂,也不想去看懂了。这些工作全部会由 Narrative JavaScript ———— 一个提供异步阻塞功能的JS扩展帮我们实现。我们只需要编写之前那个怪异的 ->() 语法, 然后通过后台预先静态编译或者前台动态编译后执行就可以实现 sleep 的效果。

Narrative JavaScript 宣称可以让你从头昏眼花的回调函数中解脱出来,编写清晰的Long Running Tasks。目前还是 alpha 的版本,在 Example 页面上有一个移动的按钮的范例。首页上也提供了源码下载。以我薄弱的基础知识,我只能勉强的看出代码中模拟了状态机的实现,希望有精通算法的朋友能为我们解析。

最后,还是我一直以来的观点: 除非很必要,否则请保持JavaScript的简单。在JavaScript 能提供原生的线程支持之前,或许我们可以改变设计以避免异步阻塞的应用。

 
     
 
 
继续>>Ajax
[第1页][第2页][下一页]
 
内容导航  
第1页AOP in JavaScript 第2页Ajax
上一篇 : 风云防火墙个人版功能特.. 下一篇风云防火墙个人版功能特..
 
  您要为所发表的言论的后果负责,请各位遵纪守法并注意文明用语
标题:  

[ 关于本站 ] [ 广告服务 ] [ 商务合作 ] [ 联系我们 ] [ 合作伙伴 ] [ 法律顾问 ] [ 网站地图 ]
千橡公司 京ICP证041489号 Copyright (c) 1997-2007 All Right Reserved.