重構JS代碼 - 讓JS代碼平面化


js中的嵌套函數用的很多,很牛叉,那為何要平面化?

  • 易懂(自己及他人)
  • 易修改(自己及他人)


平時Ajax調用寫法(基於jQuery)

$.post('url', jsonObj,
                function (data) 
                {
                      if(data)
                      {
                           var tips = $.ligerDialog.tip({ title: 'Tip', content: 'Operation successful!' });
                           setTimeout(function () { tips.close(); }, 2000);
                      }
                      else
                      {
                            var tips = $.ligerDialog.tip({ title: 'Tip', content: 'Operation Failed!' });
                            setTimeout(function () { tips.close(); }, 2000);
                      }
                }
        );

 


缺點是什么?

  1. 函數嵌套后,理解起來比較吃力
  2. 函數嵌套后,一行函數調用寫成了很多行,很容易因為逗號、括號等造成語法錯誤
  3. jQuery和liger在應用代碼中強耦合,要是以后要更換UI框架,需要進行地毯式搜索...

 

加入延遲特性 - Deferred

var ajaxHandler = $.post('url', params);
ajaxHandler.done(checkServerResponse);


var checkServerResponse=function(result)
{
      if(result)
       {
             var tips = $.ligerDialog.tip({ title: 'Tip', content: 'Operation successful!' });
              setTimeout(function () { tips.close(); }, 2000);
        }
        else
        {
                var tips = $.ligerDialog.tip({ title: 'Tip', content: 'Operation Failed!' });
                setTimeout(function () { tips.close(); }, 2000);
         }
}

 

釋疑:

  1. 改后的js與先前的沒有很大區別:如果js采用了OO方式編寫,再來看這段代碼就很清晰了(可以簡單的把checkServerResponse理解為一個private的class方法,這樣會很容易理解編寫意圖)
  2. 要是有多個ajax請求呢?可以寫成$.when($.post('url1'), $.post('url2')).done(this.checkServerResponse);類似於合並的意思,並且checkServerResponse函數的參數是2個,分別對應2個ajax請求的result
  3. 要是有多個后續請求呢?可以寫成$.when($.post(url)).then(handler1).then(handler2).done(successHandler).always(alwaysHandler).fail(failHandler);

 

用jQuery的事件來解耦 - 不依賴具體技術

先要注冊事件:

$(document).on("saveSuccess", onSaveSuccess);
$(document).on("saveFail", onSaveFail);

 

然后改造checkServerResponse函數:

var checkServerResponse= function (result) {
        if (result)
            $(document).trigger("saveSuccess");
        else
            $(document).trigger("saveFail");
    }

 

好處:

邏輯代碼具體不依賴於具體技術,比如上面的onSaveSuccess和onSaveFail,可以是下面的ligerUI:

onSaveSuccess: function () {
        var tips = $.ligerDialog.tip({ title: 'Tip', content: 'OK!' });
        setTimeout(function () { tips.close(); }, 2000);
    },
    onSaveFail: function () {
        var tips = $.ligerDialog.tip({ title: 'Tip', content: 'Fail!' });
        setTimeout(function () { tips.close(); }, 2000);
    }

 

也可以是下面的:

onSaveSuccess: function () {
        alert("OK");
    },
    onSaveFail: function () {
        alert("Fail");
    },

 

其實就是接口隔離的原理。

 

用Pub/Sub模式來解耦 - 不依賴具體技術

這種方式比起上面jQuery原生的事件處理方式更加專業,比如:amplify

使用方式就看基本類似,如下:

amplify.subscribe("saveSuccess", this.onSaveSuccess);
amplify.subscribe("saveFail", this.onSaveFail);


checkServerResponse: function (result) {
        if (result)
            amplify.publish("saveSuccess");
        else
            amplify.publish("saveFail");
}

 

amplify比jQuery原生的事件好的地方在於amplify支持優先級,並且可以在訂閱函數中控制是否繼續執行后續的訂閱函數,具體用法大家可以參考amplify官網。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM