【问题标题】:It this way of using callbacks and parameters correct?这种使用回调和参数的方式正确吗?
【发布时间】:2018-07-17 11:30:01
【问题描述】:

我目前正在学习callbacks,但我不确定下面的使用方式,尤其是涉及parameter- passing 回调showSuccessMessageshowErrorMessagesignupUser 完全optimal?当您可以 general versus concrete 方式 name 回调/参数时,我也感到困惑?

如果我的代码不正确,您能否优化我的代码并解释一下,好吗?

     // GLOBAL ARRAY for storing any DATA from the SERVER
     var ajDataFromServer = [];

      // Main ajax function using callback for posting data to the server
      function postAjax( sUrl , frmData, callback ){
                  var ajax = new XMLHttpRequest();
                  ajax.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                        var ajDataFromServer = JSON.parse(this.responseText);
                        callback( ajDataFromServer, showSuccessMessage, showErrorMessage );
                    }
                }           
                  ajax.open( "POST", sUrl , true );
                  var jFrm = new FormData( frmData );
                  ajax.send( jFrm )                 
                }


/************************************************************************/
/************************************************************************/
/************************************************************************/


      // DO the SIGNUP, POST data to the SERVER with AJAX

      btnSignupForm.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, signupUser );
      });

      function signupUser( ajUserDataFromServer, showSuccessMessage, showErrorMessage  ) {

                  if ( ajUserDataFromServer.status == "ok" ) {

                      //console.log( "SIGNUP SUCCESFULL" );
                      pageLogin.style.display = "flex";
                      pageSignup.style.display = "none";
                      showSuccessMessage( "Account succesfully created - Signup please" );

                  } else {

                      //console.log( "SIGNUP FAIL - TRY AGAIN" );
                      pageViewProducts.style.display = "none";
                      pageLogin.style.display = "none";
                      pageSignup.style.display = "flex";
                      showErrorMessage( "Signup Failed - Try again" );
                  }
              }

      /************************************************************************/
      /************************************************************************/
      /************************************************************************/


      function showSuccessMessage ( sSuccessMessage ) {
        var alblMessages = document.getElementsByClassName( "lblMessage" );
          for ( var i = 0; i < alblMessages.length; i++ ) { 
            alblMessages[i].innerHTML = sSuccessMessage.fontcolor("#549839");
          }   
      }

      /************************************************************************/
      /************************************************************************/
      /************************************************************************/


      function showErrorMessage (sErrorMessage) {
        var alblMessages = document.getElementsByClassName( "lblMessage" );
          for ( var i = 0; i < alblMessages.length; i++ ) { 
            alblMessages[i].innerHTML = sErrorMessage.fontcolor("red");
          }
      }

【问题讨论】:

    标签: javascript callback parameter-passing


    【解决方案1】:

    除了您在不同范围内有具有相同名称 (showSuccessMessage/showErrorMessage) 的“不同”变量这一事实之外(这是完全有效的,并且在嵌套大量函数调用级别时可用于识别参数,但它可能会在学习时引入混乱),这看起来是正确的。

    我在设计中看到的唯一缺点是postAjax 正在全局调用showSuccessMessageshowErrorMessage,因此当您调用postAjax 时,您无法选择消息的显示方式。同样,如果postAjax 永远不会使用其他函数传递给signupUser,那么对这些函数进行全局调用是完全有效的,但这使得将这些作为参数传递给这个函数是无用的,因为signupUser 可以直接从全局变量。这种设计可能有用的单一情况:如果您有除 postAjax 之外的其他函数,可以使用不同的消息处理程序调用 signupUser

    所以这实际上取决于你打算如何使用这些函数,如果你有一个可以调用不同回调的函数,一个回调参数是合理的,或者它可以直接调用这些函数。

    如果您希望在调用第一个函数(postAjax)时能够控制消息显示,您应该稍微更改一下代码。更通用的控制方式,可以允许更多的可能性,是使用匿名回调函数,传递给回调的唯一参数是数据:

      // Main ajax function using callback for posting data to the server
      function postAjax( sUrl , frmData, callback ){
          /*code*/
          callback( ajDataFromServer );
          /*code*/                
      }
    
      //using first set of message functions
      btnSignupForm.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, function(data){
              signupUser(data, showSuccessMessage, showErrorMessage);
          });
      });
      //using second set for another button
      btnSignupForm2.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, function(data){
              signupUser(data, showSuccessMessage2, showErrorMessage2);
          });
      });
    
      function signupUser( ajUserDataFromServer, showSuccessMessage, showErrorMessage  ) {
          /*code*/
      }
    
      function showSuccessMessage ( sSuccessMessage ) {
          /*code*/
      }
      function showErrorMessage (sErrorMessage) {
          /*code*/
      }
    
      function showSuccessMessage2 ( sSuccessMessage ) {
          /*code*/
      }
      function showErrorMessage2 (sErrorMessage) {
          /*code*/
      }
    

    编辑以下 cmets: 在谈论默认值时,更多的是使用您的“全局”消息函数,但可以重新定义一些回调函数。同样,在您的情况下这不是必需的,但知道如何做仍然很好:

      // Main ajax function using callback for posting data to the server
      // it still sends only the data to its callback
      function postAjax( sUrl , frmData, callback ){
          /*code*/
          callback( ajDataFromServer );
          /*code*/                
      }
    
      //using default set of message functions:
      //just pass the function to use as you did in original code, no need for
      //an anonymous function. This function will be passed only the data (cf postAjax code),
      //and because 2 arguments are missing in its definition, it will use its default ones:
      btnSignupForm.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, signupUser);
      });
    
      //redefining the message callbacks:
      //the trick here is to use an anonymous function like in precedent code.
      //It is this anonymous function that will be called by postAjax. But now
      //we manually make the call to signupUser inside, so we can decide to use
      //another set of message callbacks by filling the 2nd and 3rd parameters:
      btnSignupForm2.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, function(data) {
              signupUser(data, showSuccessMessage2, showErrorMessage2);
          });
      });
    
      function signupUser( ajUserDataFromServer, showSuccessMessageParam, showErrorMessageParam ) {
          //fixed default values for the message functions:
          if(undefined === showSuccessMessageParam){
              showSuccessMessageParam = showSuccessMessage;
          }
          if(undefined === showErrorMessageParam){
              showErrorMessageParam = showErrorMessage;
          }
          /*code*/
          //rest of the code will use the param variables:
          if(isSuccess){
              showSuccessMessageParam('...');
          }else{
              showErrorMessageParam('...');
          }
      }
    
      function showSuccessMessage ( sSuccessMessage ) {
          /*code*/
      }
      function showErrorMessage (sErrorMessage) {
          /*code*/
      }
    
      function showSuccessMessage2 ( sSuccessMessage ) {
          /*code*/
      }
      function showErrorMessage2 (sErrorMessage) {
          /*code*/
      }
    

    【讨论】:

    • 谢谢。非常好的解释它完美地澄清了我的疑问。
    • 我的计划是 postAjax 是单个主函数(用于发布数据),它将调用许多其他函数,例如 signupUserupdateUserdeleteUser,但具有相同的消息显示。所以我刚刚从你的解释中了解到,我不需要消息显示的参数。我说的对吗?
    • 基本上是的,如果不打算改变,这些函数可以直接调用消息函数。但这也取决于您是否希望能够将这些功能重新用于另一个项目。从这个角度来看,还可以做的是保留这两个参数,但对您当前拥有的消息函数使用默认值。然后,您可以使用或不使用参数来调用它们。但是,我的建议是从简单开始,仅在需要时才这样做。
    • 我根据您的想法在下面添加了更新。检查是否正确。
    • @codeDragon 更新了答案,修复了消息的默认值,因此 signupUser 可以在有或没有消息回调参数的情况下使用
    【解决方案2】:

    你在想@Kaddath 是不是这样,现在将 fCallback 作为消息的默认值,以后可以重用它们。我认为只有一个参数就足够了,因为是 if / else 情况。

    // Main ajax function using callback for posting data from the server
      function postAjax( sUrl, callback) {
               /*code*/
               callback( ajDataFromServer, fCallback );
               /*code*/
    
      }
    
      // DO the SIGNUP, POST data to the SERVER with AJAX
    
      btnSignupForm.addEventListener("click", function (e) {
          postAjax( "api_signup_users.php", frmSignup, signupUser );
      });
    
      function signupUser( ajUserDataFromServer, fCallback ) {
                      /*code*/
                      showSuccessMessage( "Account succesfully created - Signup please" );
    
                  } else {
                      /*code*/
                      showErrorMessage( "Signup Failed - Try again" );
                  }
              }
    
      /************************************************************************/
      /************************************************************************/
      /************************************************************************/
    
    
      function showSuccessMessage ( sSuccessMessage ) {
           /*code*/  
      }
    
      /************************************************************************/
      /************************************************************************/
      /************************************************************************/
    
    
      function showErrorMessage (sErrorMessage) {
            /*code*/
          }
      }
    

    【讨论】:

    • 由于不同的原因,这不起作用,首先,fCallbackpostAjax 中未定义,并且结构有点偏离,因为signupUser 中的单个fCallback 不会对于处理两种不同的情况是实用的(最终可能,但对你的情况来说过于复杂)。我将编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    相关资源
    最近更新 更多