在Ajax应用中,我们常常要频J更Ҏ一元素的倹{例如有一ID?pageBody"的元素,我们x所有文章内定w在这里显C,做到局部刷新的Ajax应用。但如果因ؓ|速较慢,使得此元素在接收信息时就被用h行其它行为,而改变此元素的内容了Q而之前的接收信息的线E还在进行着Q当此线E完成了Q又把pageBody的值改了一下,此时用户会觉得不知所措,怎么q块东西闪来闪去的?严重者,会因为子元素的消p出现JS错误的现象?br /> Z解决此问题,有两个方法:W一、在执行U程Q假设执行一ơ取gؓ一个线E)的时候,建立一个满屏的DIVQ得用h法执行其它行为;W二、制作一把锁Q把此元素锁hQ当其它U程x变它的值时先查此元素是否上锁?br /> W一U方法得用戯入了{待状态,虽然面没有hQ但与没有用Ajax的页面没什么分别,所以在非不得已的情况下都不要用此Ҏ?br /> 下面我说说第二种ҎQ-制作元素锁?br /> 其实要实现这个锁Q原理很单,与java中的U程锁有点类|可惜偶对java的线E锁理解不深入,所以在javaScript中此锁与java的线E锁应该又会有很大的不同Q甚臛_全不是一个回事?br /> 首先Q我们需要一个ObjectQ?/p>
var
_key
=
{key:key,value:
true
};
其中key为此对象的标识,value是否为真q于是否ؓ锁定?br />在java中,每一个Object对象都可以用作锁Q但javaScript中不同,而且通过
1 while(true){
2 if(condition) break;
3 }
的方法根本行不通,因ؓq个while(true)会让览器僵死,Firefox会提C是否l执行脚?IE可能会说脚本有误Q杀毒Y件可能说q是病毒Q?br /> Z能统领全局Q更灉|的掌控它Q我们把锁都攑ֈ一个数l中Q?/p>
1 var _mainlock=[];
同时Qؓ了方便应用,我用了Prototype.jsQ以扩展Array的方法,主要用这三个ҎQ?br />1、detect(iterator)Q集合中每个元素调用一ơIteratorQ返回第一个Iteratorq回True的元素,如果最l都没有为true的调用,那么q回null?br /> 2、reject(iterator)Q返回所有等于false的元素?br /> 3、each(iterator)Q把每个element做ؓW一个参敎ͼelement的index作ؓW一个参数调用iterator函数?br /> 有了它们Q我们可以创Z个Push来给 _mainlock加入唯一key的锁Q类似HashMap原理Q?br />
var
_Push
=
function
(Obj)
{

var
unIns
=
_mainlock.reject(
function
(d)
{
return
d.key
==
Obj.key;}
);
_mainlock
=
unIns;
_mainlock.push(Obj);
}
只要执行_Push(_key)可以把对象攑օq个伪HashMap中去。如果已有相同的key的对象,则会覆盖它,没有q接放入?br />
var
get
=
function
(key)
{

return
_mainlock.detect(
function
(d)
{
return
d.key
==
key;}
);
}
;
通过q个ҎQ就可以取得相应Key的锁了?br /> 因ؓJavaScript对DOM的操作有着很多未知性,不可能L通过我们预先定义的变量来满要求Q如一个列表,可能是有一行,也可能上千行Q每一行的ID又是独立的,所以我们只能用另外的方法来预见之此行ؓQ那是通过应用HashMap的特性,以string为标识的唯一Key来统领所有将可能发生的事件。因此,再写一个方法:
var
Lock
=
function
(key)
{

var
_key
=
{key:key,value:
true
}
;
_Push(_key);
return
true
;
}
;
q样Q只要有一个stringcd的keyQ就可以建立一个锁对象了。以后,寚w的徏立和获取Q都可以通过上面三个Ҏ来实?只要一个string作ؓKey来操作锁,而无需知道锁的内部是如何构造?br />接下来,我们要实现isWait(),sleep(),awake()和awakeAll()ҎQ以完善q个锁:
var
isWait
=
function
(key)
{
//
q回真表C锁Q否则表C非?/span>
var
ins
=
GDnews.get(key);
if
(ins)
return
ins.value;
return
false
;
}
;

var
sleep
=
function
(key,time)
{
//
l锁上锁指定U数Q若q秒后自动解?/span>
GDnews.Lock(key);

window.setTimeout(
function
()
{GDnews.awake(key)}
,time);
}
;

var
awake
=
function
(key)
{
//
开?/span>
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
;
}
;
以后Q当你用Prototype.js的快捷键$()Ӟ可以看看目标是否ؓisWaitQ否的话可以Lock或者sleep一下了?/p>
以上是全文内容Q请各位指点?/p>

]]>