【问题标题】:How can I decrease the complexity of this function that calls back depending on data-type?如何降低这个根据数据类型回调的函数的复杂性?
【发布时间】:2016-05-16 00:47:13
【问题描述】:

我正在调整我的身份验证 JavaScript 模块,以便我可以使用一个 JavaScript 类挂钩 .js-auth-ui 处理我的 Web 应用程序的身份验证,同时使用数据类型属性来引用正确的函数。

在扫描 DOM 中的 js 钩子后,我通过如下所示的 init 函数运行它,该函数又运行一个回调函数的 exec 函数。

我想知道是否有一种更有效的方法来编写 execAuthUi 函数而无需所有 else if,这会根据我的 linting 规则提高其“复杂性”等级。

const execAuthUi = function ( $element ) {
    const data = $element.data();

    if (data.type === "account-login-form") {
        authLoginEmail( $element, data );
    } else if (data.type === "account-logout") {
        authLogout( $element );
    } else if (data.type === "account-reset") {
        authReset( $element );
    } else if (data.type === "account-signup-form") {
        authSignup( $element );
    }
};

const initAuthUi = function ( ) {
    const $notLoaded = $_jsElements.not( ".is-initialized" );
    let $element = null;
    let i = $notLoaded.length;

    for ( i; i--; ) {
        $element = $_jsElements.eq( i );

        $element.addClass( "is-initialized" );

        execAuthUi( $element );
    }
};

【问题讨论】:

  • 也许考虑一个 switch/case 语句?
  • 我个人也不会考虑这个过于复杂的功能。也许你只是有一个过分热心的 linter。
  • @Spaceman 谢谢我同意,他们有点强硬。然而,复杂性实际上比这个例子更极端,所以我想提出一些更有效的东西。我还在处理一些其他功能:authLoginFacebook 和 authLoginTwitter。这个线程中的想法有很大帮助。谢谢!

标签: javascript function callback ecmascript-6


【解决方案1】:

使用对象映射类型到回调:

var callbackMap = {
    'account-login-form': authLoginEmail.bind(null, $element, data),
    'account-logout': authLogout.bind(null, $element),
    ...
};

callbackMap[data.type] && callbackMap[data.type]();

【讨论】:

  • 我从未意识到,除了thisArg,您还可以将常规参数与bind() 绑定。很高兴遇到这种情况。
  • 从未见过 bind 之前那是一个漂亮的功能。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 一些参考,如果其他人有同样的发现。
  • 好主意,这正是我想要的。我接受了这个想法并对其进行了一些调整。喜欢它!
【解决方案2】:

您可以将它写在“Switch”语句中,而不是使用多个 elseif。

我会做这样的事情

switch(data.type) {
  case "account-login-form": 
      authLoginEmail( $element, data );
      break;  
  case "account-logout": 
      authLogout( $element );
      break;
  case "account-reset":
      authReset( $element );
      break;
  case "account-signup-form":
      authSignup( $element );
      break;
}

如果您的方法不满足任何这些要求,您也可以使用“默认”大小写。

【讨论】:

    【解决方案3】:

    您可以进行切换并移动检查以可重复使用。

    const dataTypeAccountLoginForm = "account-login-form";
    const dataTypeAccountLogout = "account-logout";
    const dataTypeAccountReset = "account-reset";
    const dataTypeAccountSignupForm = "account-signup-form";
    
    const execAuthUi = function(ele){
      var data = ele.data();
    
      switch(data.type) {
        case dataTypeAccountLoginForm:
          authLoginEmail(ele, data);
          break;
        case dataTypeAccountLogout:
          authLogout(ele);
          break;
        case dataTypeAccountReset:
          authReset(ele);
          break;
        case dataTypeAccountSignupForm:
          authSignup(ele);
          break;
      }
    }
    

    另一种选择是抽象逻辑。我个人认为这样做有点矫枉过正。

    var dataTypeAccountLoginForm = "account-login-form";
    var dataTypeAccountLogout = "account-logout";
    var dataTypeAccountReset = "account-reset";
    var dataTypeAccountSignupForm = "account-signup-form";
    
    var uiFunctions = [{ 
        key : dataTypeAccountLoginForm,
        func : authLoginEmail
      },
      { 
        key : dataTypeAccountLogout,
        func : authLogout
      },
      { 
        key : dataTypeAccountReset,
        func : authReset
      },
      { 
        key : dataTypeAccountSignupForm,
        func :  authSignup
    }];
    
    var execAuthUi = function(ele){
      var data = ele.data();
    
      for (var i = 0; i < uiFunctions.length; i++) {
        if (uiFunctions[i].key === data.type){
          uiFunctions[i].func(ele,data);
          return;
        }
      }
    };
    

    或者你可以使用地图功能。

    var dataTypeAccountLoginForm = "account-login-form";
    var dataTypeAccountLogout = "account-logout";
    var dataTypeAccountReset = "account-reset";
    var dataTypeAccountSignupForm = "account-signup-form";
    
    var uiFunctions = [
      { 
        key : dataTypeAccountLoginForm,
        func : authLoginEmail
      },
      { 
        key : dataTypeAccountLogout,
        func : authLogout
      },
      { 
        key : dataTypeAccountReset,
        func : authReset
      },
      { 
        key : dataTypeAccountSignupForm,
        func :  authSignup
      }
    ];
    
    var execAuthUi = function(ele){
      var data = ele.data();
    
      uiFunctions.map(function(obj){
        if (obj.key === data.type)
          obj.func(ele,data);
      });
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多