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

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

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

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

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

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

(tng)
var
(tng)awake
=
function
(key)
{
//
开?/span>
(tng) (tng)
var
(tng)_key
=
{key:key,value:
false
}
;
(tng) (tng)GDnews._Push(_key);
(tng) (tng)
return
(tng)
false
;
(tng)}
;

(tng)
var
(tng)awakeAll
=
function
()
{
//
打开所有锁
(tng) (tng)
if
(
!
GDnews._mainlock) (tng)
return
(tng)
"
all
"
;
(tng) (tng)
var
(tng)newList
=
[];

(tng) (tng)GDnews._mainlock.each(
function
(d,index)
{
(tng) (tng) (tng)d.value
=
false
;
(tng) (tng) (tng)newList.push(d);
(tng) (tng)}
);
(tng) (tng)GDnews._mainlock
=
newList;
(tng) (tng)
return
(tng)
false
;
(tng)}
;
(tng)
(tng)以后Q当你用Prototype.js的快捷键$()Ӟ可以看看目标是否ؓ(f)isWaitQ否的话可以Lock或者sleep一下了(jin)?/p>
(tng)以上是全文内容Q请各位指点?/p>
(tng)

]]>