? 在Ajax應用中,我們常常要頻繁更改某一元素的值。例如有一ID為"pageBody"的元素,我們想把所有文章內容都在這里顯示,做到局部刷新的Ajax應用。但如果因為網速較慢,使得此元素在接收信息時就被用戶執行其它行為,而改變此元素的內容了,而之前的接收信息的線程還在進行著,當此線程完成了,又把pageBody的值改了一下,此時用戶會覺得不知所措,怎么這塊東西閃來閃去的?嚴重者,會因為子元素的消失而出現JS錯誤的現象。
為了解決此問題,有兩個方法:第一、在執行線程(假設執行一次取值為一個線程)的時候,建立一個滿屏的DIV,使得用戶無法執行其它行為;第二、制作一把鎖,把此元素鎖起來,當其它線程想改變它的值時先查檢此元素是否上鎖。
第一種方法使得用戶進入了等待狀態,雖然頁面沒有刷新,但與沒有使用Ajax的頁面沒什么分別,所以在非不得已的情況下都不要使用此方法。
下面我說說第二種方法--制作元素鎖。
其實要實現這個鎖,原理很簡單,與java中的線程鎖有點類似,可惜偶對java的線程鎖理解不深入,所以在javaScript中此鎖與java的線程鎖應該又會有很大的不同,甚至完全不是一個回事。
首先,我們需要一個Object,?
其中key為此對象的標識,value是否為真就等于是否為鎖定。
在java中,每一個Object對象都可以用作鎖,但javaScript中不同,而且通過
2???if(condition)?break;
3??}
的方法根本行不通,因為這個while(true)會讓瀏覽器僵死,Firefox會提示是否繼續執行腳本,IE可能會說腳本有誤,殺毒軟件可能說這是病毒!
為了能統領全局,更靈活的掌控它,我們把鎖都放到一個數組中:
同時,為了方便應用,我使用了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原理:










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







?通過這個方法,就可以取得相應Key的鎖了。
?因為JavaScript對DOM的操作有著很多未知性,不可能總是通過我們預先定義的變量來滿足要求,如一個列表,可能是有一行,也可能上千行,每一行的ID又是獨立的,所以我們只能用另外的方法來預見之此行為,那就是通過應用HashMap的特性,以string為標識的唯一Key來統領所有將可能發生的事件。因此,再寫一個方法:









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







































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