Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有更好的方法来处理Node.js/Expressjs中的嵌套回调?_Javascript_Node.js_Architecture_Callback_Express - Fatal编程技术网

Javascript 有没有更好的方法来处理Node.js/Expressjs中的嵌套回调?

Javascript 有没有更好的方法来处理Node.js/Expressjs中的嵌套回调?,javascript,node.js,architecture,callback,express,Javascript,Node.js,Architecture,Callback,Express,我使用Node.js和Expressjs进行服务器端编码,使用MongoDB作为后端。我对所有这些技术都是新手。 我需要根据请求执行一系列操作 例如在用户管理中 检查已注册的用户 如果已注册,请重新发送激活电子邮件 如果未注册,则从另一个表中获取用户id,该表将维护用户、资产等的id。【我知道MongoDB提供唯一的\u id;但我需要一个唯一的整数id作为用户id】 创建用户 发送成功或失败响应 为了实现这一点,我编写了以下代码: exports.register = function(req

我使用Node.js和Expressjs进行服务器端编码,使用MongoDB作为后端。我对所有这些技术都是新手。 我需要根据请求执行一系列操作

例如在用户管理中

  • 检查已注册的用户
  • 如果已注册,请重新发送激活电子邮件
  • 如果未注册,则从另一个表中获取用户id,该表将维护用户、资产等的id。【我知道MongoDB提供唯一的\u id;但我需要一个唯一的整数id作为用户id】
  • 创建用户
  • 发送成功或失败响应
  • 为了实现这一点,我编写了以下代码:

    exports.register = function(req,res,state,_this,callback) {
       switch(state) {
        case 1: //check user already registered or not
          _this.checkUser(req, res, ( state + 1 ), _this, _this.register, callback);
          break;
        case 2: //Already registered user so resend the activation email
          _this.resendEmail(req, res, 200, _this, _this.register, callback);
          break;
        case 3: //not registered user so get the userId from another table that will maintain the ids for user,assets etc
          _this.getSysIds(req, res, ( state + 2 ), _this, _this.register, callback);
          break;
        case 4: //create the entry in user table
          _this.createUser(req, res, ( state + 1 ), _this, _this.register, callback);
          break;
        case 200: //Create Success Response
          callback(true);
          break;
        case 101://Error
          callback(false);
          break;
        default:
          callback(false);
        break;
      }
    };
    
    检查用户代码是这样的

    exports.checkUser = function(req,res,state,_this,next,callback) {
        //check user already registered or not
        if(user) {//Already registered user so resend the activation email
           next(req,res,state,_this,callback);
        }
        else {//not registered user so get the userId
          next(req,res,(state + 1),_this,callback);
        }
    }
    
    和其他类似的功能

    第一次调用register函数将从app.get as执行

    user.register(req,res,1,this,function(status) {
    //do somthing
    });
    
    有没有更好的办法?我面临的问题是基于我必须遵循一系列行动的某些条件。我可以在嵌套回调结构中编写所有这些代码,但在这种情况下,我无法重用代码

    我老板告诉我的一个问题是,在代码中,我调用函数寄存器,并将其作为

    第1国:切库瑟

    状态3:getID

    状态4:创建用户

    最后在状态200,我刚刚从堆栈中退出?这可能会导致堆栈溢出

    有没有更好的方法来处理Node.js/Expressjs中的回调


    注意:上面是一个示例代码。我有很多类似的情况

    也许更优雅的方法是将所有可能的函数放在一个对象中,然后根据所处的状态调用所需的函数。有点像

    var States = {
       1: checkuser,
       2: resendEmail,
       3: getSysIds,
       4: createUser,
       5: whateverIsNext 
    }
    
    然后你只需要有一个函数来完成所有的事情

    function exec(req,res,state,_this,callback){
       States[state].apply(this, arguments) 
    }
    
    每个函数只需将state参数设置为所需的值,然后调用exec

    function checkUser(req,res,state,_this,callback){
        var doneRight = do_whatever_you_need;
        state = doneRight? state++: state; //just set state to whatever number it should be
        exec(req,res,state,_this,callback);
    }
    

    这样,您的步骤列表既美观又可读/可更改。您已经有了一个执行所有操作的函数,每个步骤都必须管理下一步应该是什么。如果需要,还可以将编号的步骤替换为named,这将使其更具可读性,但会失去递增/递减步骤变量的功能

    也许更优雅的方法是将所有可能的函数放在一个对象中,然后根据所处的状态调用所需的函数。有点像

    var States = {
       1: checkuser,
       2: resendEmail,
       3: getSysIds,
       4: createUser,
       5: whateverIsNext 
    }
    
    然后你只需要有一个函数来完成所有的事情

    function exec(req,res,state,_this,callback){
       States[state].apply(this, arguments) 
    }
    
    每个函数只需将state参数设置为所需的值,然后调用exec

    function checkUser(req,res,state,_this,callback){
        var doneRight = do_whatever_you_need;
        state = doneRight? state++: state; //just set state to whatever number it should be
        exec(req,res,state,_this,callback);
    }
    

    这样,您的步骤列表既美观又可读/可更改。您已经有了一个执行所有操作的函数,每个步骤都必须管理下一步应该是什么。如果需要,还可以将编号的步骤替换为named,这将使其更具可读性,但会失去递增/递减步骤变量的功能

    你把中间件、数据库层和路由处理程序混为一谈,太过工程化了。让我们让它更简单,更可重用

    首先,让我们确保我们的中间件和路由处理程序能够相互通信。这可以通过以下方式实现:

    您现在想要的是在请求处理过程中到处都有用户信息。现在,它只是电子邮件,不管它是否注册。这将是第一个独立的中间件。为了简洁起见,我们假设您通过使用电子邮件查询数据库来检测用户是否注册

    确定注册状态后,您应该发送电子邮件或创建新用户,这将是请求处理程序(app.get的最后一个参数)。在执行处理程序之前,我们希望运行
    userInfo
    (可以只传递
    userInfo
    (不是数组),但我个人更喜欢这种方式):

    请求处理程序不应该为这两个函数中发生的事情而烦恼(有多少数据库查询,谁在发送电子邮件以及如何发送)。它所知道的是,若发生错误,所提供回调的第一个参数不为null

    现在开始创建新用户。编写
    registerUser
    函数,该函数将使用ID查询表,准备用户信息并将其保存在数据库中。有关如何同步这两个操作,请参阅和其他。创建完成或出错时,调用
    callback
    ,并显示结果。这个函数应该是DB层的一部分。至少,创建
    db.js
    模块并导出重要的东西,比如
    registerUser
    ;通过电子邮件查询用户信息(在第一个中间件内部)也应该位于数据库层内部

    类似情况也适用于
    sendActivationEmail


    旁注:您可以在mongo documet中放入您想要的任何内容,而不仅仅是。

    您在这里过度工程,混合了中间件、数据库层和路由处理程序。让我们让它更简单,更可重用

    首先,让我们确保我们的中间件和路由处理程序能够相互通信。这可以通过以下方式实现:

    您现在想要的是在请求处理过程中到处都有用户信息。现在,它只是电子邮件,不管它是否注册。这将是第一个独立的中间件。为了简洁起见,我们假设您通过使用电子邮件查询数据库来检测用户是否注册

    确定注册状态后,您应该发送电子邮件或创建新用户,这将是请求处理程序(app.get的最后一个参数)。在执行处理程序之前,我们希望运行
    userInfo
    (可以只传递
    userInfo
    (不是数组),但我个人更喜欢这种方式):

    请求处理程序不应该为这两个函数中发生的事情而烦恼(有多少数据库查询,谁在发送电子邮件以及如何发送)。它只知道提供的回调的第一个参数不是