好了開始吧
重構這個其實也不是什麼大動作,主要要實現的功能嘛,就是把現有的JS代碼重新劃分一下,解耦現有模塊。然後我打算把現有的程序劃分一下模塊然後重新打包做一個命名空間實現use或者類似於java的Package的東西。那麼我只要加載一個use的js文件調用這個文件的use函數,通過設置某些參數,我可以動態地加載所需要的模塊。這個是最完美的想法(那時我很傻很天真)。好的,噩夢開始了。
前提,我低估了3個月前的自己。//好吧,下面可能會出現un文明用語~~
首先,計劃的第一天,我的打算是分離這個程序裡面最需要解耦的部分,自制控件部分。說起來,人家也嘗試著寫了一些窗體控件什麼的比如Panel.js,Button.js之類的控件這裡面有一大堆js文件,雖然我已經劃分好文件夾了,但是看到index頁面上面那一連串的<script>標簽,各種蛋疼的說。於是噩夢進入第二階段,我想加載一個JS文件,而這個JS文件可以動態地加載所有的控件JS。如果想了解"動態加載JS"的相關知識,請去度娘G娘那裡問個明白。我想應該會搜到好多3異步+1Ajax的實現。好了,這些都是廢話,參考了《高性能JavaScript》一書,產生以下代碼:
復制代碼 代碼如下:
function loadScript (url, callback){
var script = document.createElement("script");
script.type = "text/javascript";
if(script.readyState){ //IE
script.onreadystatechange = function(){
if(script.readyState == "loaded" || script.readState == "complete"){
script.onreadystatechange = null;
callback();
}
}
}else{
script.onload = function(){
callback();
}
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
好的悲劇慢慢開始,首先我的控件都是基於JQuery的那麼必然要 loadScript(jqueryURL, function(){//加載我的控件s}),好的這裡說到這裡打斷一下,下面再接上。
然後我又突發奇想要做命名空間的功能,好的研究了面向對象啊,原型鏈啊之類雜七雜八的東西然後發現這種打點引用的功能好抽象,給那本《javascript設計模式》的書忽悠的七零八落。最後在了解了原型模式之後,還是一團迷霧。好的,我覺得我要重新思考這個問題,我其實只是想要打點出控件而已,那麼我只要將我的控件作為一個對象的屬性綁定到一個全局的對象上面就好了。於是我用了自己的英文名Gssl作為一個對象得出如下結構:
復制代碼 代碼如下:
var Gssl = {}
好了回到上面打斷的地方,我的想法就是在動態加載JS的時候順便構造我的全局對象並綁定到空間名為Gssl下,具體實現如下:
復制代碼 代碼如下:
loadScript(jqueryURL, function(){
//加載我的控件s
loadScript(controlURL, function(){
//綁定控件
Gssl.control = control;
});
});
寫到這裡,測試是調通了,昨天晚上,小開心了一下,但是程序員的直覺話我知,噩夢還沒有結束。
今天早上回去把這個動態加載JS的JS文件引用到了我的頁面那裡,結果因為異步的特點,後面的代碼沒有等到這個Gssl的對象生成完成就開始執行了(我去,這不合理啊)。然後思考了一下,想在最後加載的一個控件那裡做一個ready標志位以標志Gssl到底有沒有加載完成。但是發現每個組件各自有各自的callback函數,你根本就不知道哪一個才是最後加載的,雖然代碼執行是有順序的,但是這個傳輸的並行性又讓你不能確定到底哪一個才是最後一個。好的我徹底崩潰了,於是想了一個非常2B的方法,干脆寫一個函數來卡住程序2秒吧,兩秒肯定可以了~。然後發現setTimeout TM不能卡代碼的,他的好基友setIXXXXX也是不能卡代碼的。好的,朕生氣了,寫了一個死循環循環判斷ready位。好的,浏覽器不干了。
回到原點,我開始考慮嘗試遞歸式的加載就是在Callback的時候才去加載下一個控件,這樣我就能知道控件什麼時候加載完了。但是仔細一想,我擦,如果要這樣加載那麼我還動態加載個屁啊,這不就一點也沒有提高到效率麼。然後看了各種框架的ready方法的實現。嗯 TM單文件的就是IMBA啊。那麼擺在我面前的就只有一條路了,把所有的控件都寫在一個JS上面。這樣根本就是避重就輕啊。
然後我就不斷在這種提出解決方案,然後不斷自我吐槽中度過了噩夢般的一天。快下班了,我還在不停地思考這個問題究竟有沒有解。然後腦裡面第三個聲音開始了,志偉啊~(呵呵本人的名字就是這個了~),真的有必要麼?好的,不得不承認,每次脫離噩夢就得靠他。然後我把整個項目的文件夾打開每層每層地點開又退回去,然後思考,好吧,不是寫小說,這些思考時候的小動作就不描述了(我會告訴你我想問題的時候會好像精神病人一樣犯傻麼)。最後我發現就算我把這些模塊都抽離了,去到其他的項目還是要做出一定的修改,雖然有做接口,但是接口是接後台的,我模塊間的接口還沒有做。這樣的抽離會伴隨著一大堆額外的支付(估計的啦,但是根據經驗這些是必然的~),並且新的JS框架在整體框架裡面並不兼容(下班的時候發現某些資源訪問出問題了),雖然不死心,但是還是放棄了(萬惡的進度,次奧)。這一版的代碼也沒有做保存,呃SVN也沒有更新上去~。我的U盤移硬上面也沒有備份,但是所有的源碼都給我一怒之下付諸Delete了。僅以此篇日志留作紀念。
教訓就是如果一開始我就有一個前端模塊化的思想,就不會走到今天這一步了。以我的能力完全可以做到,但是現在已經積重難返了~還是那些萬惡的奶粉廣告,讓寶寶有個好的開始,那麼我的就是讓代碼有個好的開始吧~原諒我這個不及格的粑粑~~ (T_T)
另外我知道博客園是個神奇的地方,如果有同人遇到相同的困擾並且切實解決了的話,可否分享一下呢?有回必復!