Javascript 有没有更好的方法来处理Node.js/Expressjs中的嵌套回调?
我使用Node.js和Expressjs进行服务器端编码,使用MongoDB作为后端。我对所有这些技术都是新手。 我需要根据请求执行一系列操作 例如在用户管理中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
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
(不是数组),但我个人更喜欢这种方式):
请求处理程序不应该为这两个函数中发生的事情而烦恼(有多少数据库查询,谁在发送电子邮件以及如何发送)。它只知道提供的回调的第一个参数不是