? 在Ajax應(yīng)用中,我們常常要頻繁更改某一元素的值。例如有一ID為"pageBody"的元素,我們想把所有文章內(nèi)容都在這里顯示,做到局部刷新的Ajax應(yīng)用。但如果因?yàn)榫W(wǎng)速較慢,使得此元素在接收信息時(shí)就被用戶執(zhí)行其它行為,而改變此元素的內(nèi)容了,而之前的接收信息的線程還在進(jìn)行著,當(dāng)此線程完成了,又把pageBody的值改了一下,此時(shí)用戶會(huì)覺得不知所措,怎么這塊東西閃來閃去的?嚴(yán)重者,會(huì)因?yàn)樽釉氐南Ф霈F(xiàn)JS錯(cuò)誤的現(xiàn)象。
為了解決此問題,有兩個(gè)方法:第一、在執(zhí)行線程(假設(shè)執(zhí)行一次取值為一個(gè)線程)的時(shí)候,建立一個(gè)滿屏的DIV,使得用戶無法執(zhí)行其它行為;第二、制作一把鎖,把此元素鎖起來,當(dāng)其它線程想改變它的值時(shí)先查檢此元素是否上鎖。
第一種方法使得用戶進(jìn)入了等待狀態(tài),雖然頁面沒有刷新,但與沒有使用Ajax的頁面沒什么分別,所以在非不得已的情況下都不要使用此方法。
下面我說說第二種方法--制作元素鎖。
其實(shí)要實(shí)現(xiàn)這個(gè)鎖,原理很簡(jiǎn)單,與java中的線程鎖有點(diǎn)類似,可惜偶對(duì)java的線程鎖理解不深入,所以在javaScript中此鎖與java的線程鎖應(yīng)該又會(huì)有很大的不同,甚至完全不是一個(gè)回事。
首先,我們需要一個(gè)Object,?
其中key為此對(duì)象的標(biāo)識(shí),value是否為真就等于是否為鎖定。
在java中,每一個(gè)Object對(duì)象都可以用作鎖,但javaScript中不同,而且通過
2???if(condition)?break;
3??}
的方法根本行不通,因?yàn)檫@個(gè)while(true)會(huì)讓瀏覽器僵死,F(xiàn)irefox會(huì)提示是否繼續(xù)執(zhí)行腳本,IE可能會(huì)說腳本有誤,殺毒軟件可能說這是病毒!
為了能統(tǒng)領(lǐng)全局,更靈活的掌控它,我們把鎖都放到一個(gè)數(shù)組中:
同時(shí),為了方便應(yīng)用,我使用了Prototype.js,以擴(kuò)展Array的方法,主要用這三個(gè)方法:
1、detect(iterator):集合中每個(gè)元素調(diào)用一次Iterator,返回第一個(gè)使Iterator返回True的元素,如果最終都沒有為true的調(diào)用,那么返回null。
?2、reject(iterator):返回所有等于false的元素。
?3、each(iterator):把每個(gè)element做為第一個(gè)參數(shù),element的index作為第一個(gè)參數(shù)調(diào)用iterator函數(shù)。
?有了它們,我們可以創(chuàng)建一個(gè)Push來給 _mainlock加入唯一key的鎖,類似HashMap原理:










只要執(zhí)行_Push(_key)就可以把對(duì)象放入這個(gè)偽HashMap中去。如果已有相同的key的對(duì)象,則會(huì)覆蓋它,沒有就直接放入。







?通過這個(gè)方法,就可以取得相應(yīng)Key的鎖了。
?因?yàn)镴avaScript對(duì)DOM的操作有著很多未知性,不可能總是通過我們預(yù)先定義的變量來滿足要求,如一個(gè)列表,可能是有一行,也可能上千行,每一行的ID又是獨(dú)立的,所以我們只能用另外的方法來預(yù)見之此行為,那就是通過應(yīng)用HashMap的特性,以string為標(biāo)識(shí)的唯一Key來統(tǒng)領(lǐng)所有將可能發(fā)生的事件。因此,再寫一個(gè)方法:









這樣,只要有一個(gè)string類型的key,就可以建立一個(gè)鎖對(duì)象了。以后,對(duì)鎖的建立和獲取,都可以通過上面三個(gè)方法來實(shí)現(xiàn),只要一個(gè)string作為Key來操作鎖,而無需知道鎖的內(nèi)部是如何構(gòu)造。
接下來,我們要實(shí)現(xiàn)isWait(),sleep(),awake()和awakeAll()方法,以完善這個(gè)鎖:







































?以后,當(dāng)你使用Prototype.js的快捷鍵$()時(shí),就可以看看目標(biāo)是否為isWait,否的話就可以Lock或者sleep一下了。
?以上就是全文內(nèi)容,請(qǐng)各位指點(diǎn)。
?
posted @ 2006-09-14 18:26 govo 閱讀(369) | 評(píng)論 (0) | 編輯 收藏