JS前端框架關于重構的失敗經(jīng)驗分享
好了開始吧
重構這個其實也不是什么大動作,主要要實現(xiàn)的功能嘛,就是把現(xiàn)有的JS代碼重新劃分一下,解耦現(xiàn)有模塊。然后我打算把現(xiàn)有的程序劃分一下模塊然后重新打包做一個命名空間實現(xiàn)use或者類似于java的Package的東西。那么我只要加載一個use的js文件調(diào)用這個文件的use函數(shù),通過設置某些參數(shù),我可以動態(tài)地加載所需要的模塊。這個是最完美的想法(那時我很傻很天真)。好的,噩夢開始了。
前提,我低估了3個月前的自己。//好吧,下面可能會出現(xiàn)un文明用語~~
首先,計劃的第一天,我的打算是分離這個程序里面最需要解耦的部分,控件部分。說起來,人家也嘗試著寫了一些窗體控件什么的比如Panel.js,Button.js之類的控件這里面有一大堆js文件,雖然我已經(jīng)劃分好文件夾了,但是看到index頁面上面那一連串的<script>標簽,各種的說。于是噩夢進入第二階段,我想加載一個JS文件,而這個JS文件可以動態(tài)地加載所有的控件JS。如果想了解"動態(tài)加載JS"的相關知識,請去度娘G娘那里問個明白。我想應該會搜到好多3異步+1Ajax的實現(xiàn)。好了,這些都是廢話,參考了《高性能JavaScript》一書,產(chǎn)生以下代碼:
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}),好的這里說到這里打斷一下,下面再接上。
然后我又突發(fā)奇想要做命名空間的功能,好的研究了面向?qū)ο蟀?,原型鏈啊之類雜七雜八的東西然后發(fā)現(xiàn)這種打點引用的功能好抽象,給那本《javascript設計模式》的書忽悠的七零八落。最后在了解了原型模式之后,還是一團迷霧。好的,我覺得我要重新思考這個問題,我其實只是想要打點出控件而已,那么我只要將我的控件作為一個對象的屬性綁定到一個全局的對象上面就好了。于是我用了自己的英文名Gssl作為一個對象得出如下結構:
var Gssl = {}
好了回到上面打斷的地方,我的想法就是在動態(tài)加載JS的時候順便構造我的全局對象并綁定到空間名為Gssl下,具體實現(xiàn)如下:
loadScript(jqueryURL, function(){
//加載我的控件s
loadScript(controlURL, function(){
//綁定控件
Gssl.control = control;
});
});
寫到這里,測試是調(diào)通了,昨天晚上,小開心了一下,但是程序員的直覺話我知,噩夢還沒有結束。
今天早上回去把這個動態(tài)加載JS的JS文件引用到了我的頁面那里,結果因為異步的特點,后面的代碼沒有等到這個Gssl的對象生成完成就開始執(zhí)行了(我去,這不合理?。H缓笏伎剂艘幌?,想在最后加載的一個控件那里做一個ready標志位以標志Gssl到底有沒有加載完成。但是發(fā)現(xiàn)每個組件各自有各自的callback函數(shù),你根本就不知道哪一個才是最后加載的,雖然代碼執(zhí)行是有順序的,但是這個傳輸?shù)牟⑿行杂肿屇悴荒艽_定到底哪一個才是最后一個。好的我徹底崩潰了,于是想了一個非常2B的方法,干脆寫一個函數(shù)來卡住程序2秒吧,兩秒肯定可以了~。然后發(fā)現(xiàn)setTimeout TM不能卡代碼的,他的好友setIXXXXX也是不能卡代碼的。好的,朕生氣了,寫了一個死循環(huán)循環(huán)判斷ready位。好的,瀏覽器不干了。
回到原點,我開始考慮嘗試遞歸式的加載就是在Callback的時候才去加載下一個控件,這樣我就能知道控件什么時候加載完了。但是仔細一想,我擦,如果要這樣加載那么我還動態(tài)加載個屁啊,這不就一點也沒有提高到效率么。然后看了各種框架的ready方法的實現(xiàn)。嗯 TM單文件的就是IMBA啊。那么擺在我面前的就只有一條路了,把所有的控件都寫在一個JS上面。這樣根本就是避重就輕啊。
然后我就不斷在這種提出解決方案,然后不斷自我吐槽中度過了噩夢般的一天??煜掳嗔?,我還在不停地思考這個問題究竟有沒有解。然后腦里面第三個聲音開始了,志偉啊~(呵呵本人的名字就是這個了~),真的有必要么?好的,不得不承認,每次脫離噩夢就得靠他。然后我把整個項目的文件夾打開每層每層地點開又退回去,然后思考,好吧,不是寫小說,這些思考時候的小動作就不描述了(我會告訴你我想問題的時候會好像精神病人一樣犯傻么)。最后我發(fā)現(xiàn)就算我把這些模塊都抽離了,去到其他的項目還是要做出一定的修改,雖然有做接口,但是接口是接后臺的,我模塊間的接口還沒有做。這樣的抽離會伴隨著一大堆額外的支付(估計的啦,但是根據(jù)經(jīng)驗這些是必然的~),并且新的JS框架在整體框架里面并不兼容(下班的時候發(fā)現(xiàn)某些資源訪問出問題了),雖然不死心,但是還是放棄了(萬惡的進度,次奧)。這一版的代碼也沒有做保存,呃SVN也沒有更新上去~。我的U盤移硬上面也沒有備份,但是所有的源碼都給我一怒之下付諸Delete了。僅以此篇日志留作紀念。
另外我知道博客園是個神奇的地方,如果有同人遇到相同的困擾并且切實解決了的話,可否分享一下呢?有回必復!
相關文章
基于JavaScript實現(xiàn)繼承機制之原型鏈(prototype chaining)的詳解
我們知道在JavaScript中定義類的原型方式,而原型鏈擴展了這種方式,以一種有趣的方式實現(xiàn)繼承機制。prototype 對象是個模板,要實例化的對象都以這個模板為基礎??偠灾?,prototype 對象的任何屬性和方法都被傳遞給那個類的所有實例。原型鏈利用這種功能來實現(xiàn)繼承機制2013-05-05js實現(xiàn)div模擬模態(tài)對話框展現(xiàn)URL內(nèi)容
這篇文章主要介紹了js實現(xiàn)div模擬模態(tài)對話框展現(xiàn)URL內(nèi)容的功能,涉及javascript動態(tài)操作頁面元素樣式與ajax調(diào)用的相關技巧,需要的朋友可以參考下2016-05-05