posts - 3, comments - 1, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2006年9月8日

   在Ajax应用中,我们常常要频繁更改某一元素的值。例如有一ID为"pageBody"的元素,我们想把所有文章内容都在这里显示,做到局部刷新的Ajax应用。但如果因为网速较慢,使得此元素在接收信息时就被用户执行其它行为,而改变此元素的内容了,而之前的接收信息的线程还在进行着,当此线程完成了,又把pageBody的值改了一下,此时用户会觉得不知所措,怎么这块东西闪来闪去的?严重者,会因为子元素的消失而出现JS错误的现象。
  为了解决此问题,有两个方法:第一、在执行线程(假设执行一次取值为一个线程)的时候,建立一个满屏的DIV,使得用户无法执行其它行为;第二、制作一把锁,把此元素锁起来,当其它线程想改变它的值时先查检此元素是否上锁。
  第一种方法使得用户进入了等待状态,虽然页面没有刷新,但与没有使用Ajax的页面没什么分别,所以在非不得已的情况下都不要使用此方法。
  下面我说说第二种方法--制作元素锁。
  其实要实现这个锁,原理很简单,与java中的线程锁有点类似,可惜偶对java的线程锁理解不深入,所以在javaScript中此锁与java的线程锁应该又会有很大的不同,甚至完全不是一个回事。
  首先,我们需要一个Object, 

var  _key = {key:key,value: true };

其中key为此对象的标识,value是否为真就等于是否为锁定。
在java中,每一个Object对象都可以用作锁,但javaScript中不同,而且通过

1  while(true){
2   if(condition) break;
3  }

的方法根本行不通,因为这个while(true)会让浏览器僵死,Firefox会提示是否继续执行脚本,IE可能会说脚本有误,杀毒软件可能说这是病毒!
  为了能统领全局,更灵活的掌控它,我们把锁都放到一个数组中:

1  var _mainlock=[];

同时,为了方便应用,我使用了Prototype.js,以扩展Array的方法,主要用这三个方法:
1、detect(iterator):集合中每个元素调用一次Iterator,返回第一个使Iterator返回True的元素,如果最终都没有为true的调用,那么返回null。
 2、reject(iterator):返回所有等于false的元素。
 3、each(iterator):把每个element做为第一个参数,element的index作为第一个参数调用iterator函数。
 有了它们,我们可以创建一个Push来给 _mainlock加入唯一key的锁,类似HashMap原理:

  var  _Push = function (Obj) {
  
var  unIns = _mainlock.reject( function (d) { return  d.key == Obj.key;} );
  _mainlock
= unIns;
  _mainlock.push(Obj);
 }


只要执行_Push(_key)就可以把对象放入这个伪HashMap中去。如果已有相同的key的对象,则会覆盖它,没有就直接放入。

var  get = function (key) {
  
return  _mainlock.detect( function (d) { return  d.key == key;} );
 }
;


 通过这个方法,就可以取得相应Key的锁了。
 因为JavaScript对DOM的操作有着很多未知性,不可能总是通过我们预先定义的变量来满足要求,如一个列表,可能是有一行,也可能上千行,每一行的ID又是独立的,所以我们只能用另外的方法来预见之此行为,那就是通过应用HashMap的特性,以string为标识的唯一Key来统领所有将可能发生的事件。因此,再写一个方法:

  var  Lock = function (key) {
  
var  _key = {key:key,value: true } ;
  _Push(_key);
  
return   true ;
 }
;


这样,只要有一个string类型的key,就可以建立一个锁对象了。以后,对锁的建立和获取,都可以通过上面三个方法来实现,只要一个string作为Key来操作锁,而无需知道锁的内部是如何构造。
接下来,我们要实现isWait(),sleep(),awake()和awakeAll()方法,以完善这个锁:

  var  isWait = function (key) { // 返回真表示锁,否则表示非锁
   var  ins = GDnews.get(key);
  
if (ins)  return  ins.value;
  
return   false ;
 }
;
 
var  sleep = function (key,time) { // 给锁上锁指定秒数,若干秒后自动解锁
  GDnews.Lock(key);
  window.setTimeout(
function () {GDnews.awake(key)} ,time);
 }
;
 
var  awake = function (key) { // 强行开锁
   var  _key = {key:key,value: false } ;
  GDnews._Push(_key);
  
return   false ;
 }
;
 
var  awakeAll = function () { // 强行打开所有锁
   if ( ! GDnews._mainlock)  return   " all " ;
  
var  newList = [];
  GDnews._mainlock.each(
function (d,index) {
   d.value
= false ;
   newList.push(d);
  }
);
  GDnews._mainlock
= newList;
  
return   false ;
 }
;
 



 以后,当你使用Prototype.js的快捷键$()时,就可以看看目标是否为isWait,否的话就可以Lock或者sleep一下了。

 以上就是全文内容,请各位指点。

 

posted @ 2006-09-14 18:26 govo 阅读(360) | 评论 (0)编辑 收藏

在javaworld上我问了一个问题:
      当我们有了Ajax了,基本所有页面都可能用Html为文件后缀了,TAG不用写了,<%%>符号也不用写了,那么,我们还用得着Struts或JSF吗? 
      然后热心的大虾kebin_liu 给我指点了迷津,现在把他的话抄下:

用一句俗語來解釋會比較容易瞭解,那就是『殺雞焉用牛刀』。
Struts等 web framework算是牛刀,那AJAX就是殺雞小刀,殺雞小刀能不能取代牛刀?當然可以,只是用起來會不順手不方便而已。但反過來牛刀能不能取代小刀?答案是沒辦法完全取代,因為會有死角。

web framework適合處理web ap的運作流程,而AJAX適合資料傳輸與頁面處理,如果從所有的web ap說穿了就只是資料傳輸與頁面處理的角度去思考,的確會認為AJAX可以替代一切 web framework。只是當一切都改用 AJAX來處理的時候,開發的工作勢必變得零碎繁瑣,就像用小刀殺牛,最終牛一定會死,但是操刀者辛苦不說,那頭牛也飽受凌遲。

而因為 web framework無法處理純粹頁面部分的控制,所以不管有沒有AJAX,web ap都離不開 script,因為 web framework有這個死角,所以說webframework無法取代 AJAX。

再用一個比喻,web framework就像是建築的主體,AJAX則是裝潢,一個結構穩固又適度裝潢的房子,才是最舒適的居住空間。只有裝潢的房子,其實就是樣品屋,雖然也可以住人,但是結構畢竟不穩。而過渡裝潢或沒有裝潢的房子,一樣讓人住起來不舒服。

總之,web framework是架構面,AJAX則偏重於UI處理,二者的角色是相輔相成才對,並沒有互相衝突。不管有沒有AJAX,不用 framework本來就還是可以開發 web ap,但我們從來就不會因此說 framework是多餘的,有了AJAX也是一樣的。

posted @ 2006-09-08 01:51 govo 阅读(301) | 评论 (0)编辑 收藏

今天鼓起勇气向管理员申请BlogJava,希望能以此激励自己,能在这最后一年的大学活里,更加努力!

posted @ 2006-09-08 01:34 govo 阅读(163) | 评论 (0)编辑 收藏