Javascript node.js回调设计-如何在回调中使用res
我有一个路由,它进行了一些处理,而不是返回回调。 代码如下:Javascript node.js回调设计-如何在回调中使用res,javascript,node.js,callback,Javascript,Node.js,Callback,我有一个路由,它进行了一些处理,而不是返回回调。 代码如下: router.get('/login', function(req,res,next) { // send call to login function. var ID= req.query.ID; var Password = req.query.Password ctlLogin.login(ID,Password, LoginCallback); }); function LoginCallback(
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password, LoginCallback);
});
function LoginCallback(err,myLoginResult)
{
res.json(myLoginResult);
}
登录函数检查数据库中是否存在用户/密码,并返回:
loginCallback(result);
我的问题-LoginCallBack功能不知道对象的大小。
我知道我可以将它传输到登录模块,只是为了让它作为回调函数的参数传回给我,但这似乎是一个糟糕的设计,已经糟糕到我需要将回调函数发送到登录方法
有没有更好的方法来做到这一点,并且仍然有可读的代码?我认为最好的方法是使用以下代码片段:
ctlLogin.login(ID,Password, function(myLoginResult){
res.json(myloginResult);
});
在这种情况下,您的登录功能中应该有如下内容:
login(ID, Password, callback){
//your treatment here
callback(result)
}
我认为最好的方法是使用以下代码片段:
ctlLogin.login(ID,Password, function(myLoginResult){
res.json(myloginResult);
});
在这种情况下,您的登录功能中应该有如下内容:
login(ID, Password, callback){
//your treatment here
callback(result)
}
您可以创建自己的中间件来处理在不同功能上的登录。下面是我为您创建的一个简单的express应用程序:
var app = require('express')();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
function login(req, res, next) {
// login check
console.log(req.query);
if(req.query.ID === '1' && req.query.Password === 'password') {
return next();
}
// if check above is false
res.send({success: false});
}
app.get('/login', login, function (req, res, next) {
res.send({success: true});
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
您可以看到我在post routeapp.get('/login',login,func…
中插入了函数
现在,如果您使用这些url参数访问页面,您将看到成功消息。如果您更改任何参数名称或值,它将返回success:false
您应该阅读更多有关创建自己的的内容。您可以创建自己的中间件来处理您在不同功能上的登录。下面是我为您创建的一个简单的express应用程序:
var app = require('express')();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
function login(req, res, next) {
// login check
console.log(req.query);
if(req.query.ID === '1' && req.query.Password === 'password') {
return next();
}
// if check above is false
res.send({success: false});
}
app.get('/login', login, function (req, res, next) {
res.send({success: true});
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
您可以看到我在post routeapp.get('/login',login,func…
中插入了函数
现在,如果您使用这些url参数访问页面,您将看到成功消息。如果您更改任何参数名称或值,它将返回success:false
您应该阅读更多关于创建自己的您正在使用loginCallback超出功能范围(req、res、next),因为req、res和next超出了无法访问的范围。您可以像这样访问它
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
function LoginCallback(err,myLoginResult){
res.json(myLoginResult);
}
ctlLogin.login(ID,Password, LoginCallback);
});
或者,如果ctlLogin函数支持PROMITE,则可以使用PROMITE而不是回调
ctlLogin.login(ID,Password)
.then(LoginCallback)
.catch(console.log(err))
或者,如果希望LoginCallback函数超出函数范围(req、res、next),则需要通过创建回调函数在该函数中传递res,然后通过传递错误、结果和res或使用bind调用LoginCallback函数
function sendResponseToSever(res, err, myLoginResult){
if(err){
return res.send({
errors: err,
status: 500 // what ever status code you want to set
});
}
return res.json(results);
}
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password, sendResponseToSever.bind(null, res)
//using bind function
// OR
ctlLogin.login(ID,Password, function(err, myLoginResult){
sendResponseToSever(err, myLoginResult, res);
// now sendResponseToSever is a generic function which you can call
// from any route
});
});
});
但若你们想避免地狱,最受欢迎的方式是使用承诺。
正如您所提到的,要避免嵌套,可以使用承诺来避免嵌套
请查看您是否想了解promises您正在使用loginCallback超出功能范围(req、res、next),因为req、res和next超出了无法访问的范围。您可以像这样访问它
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
function LoginCallback(err,myLoginResult){
res.json(myLoginResult);
}
ctlLogin.login(ID,Password, LoginCallback);
});
或者,如果ctlLogin函数支持PROMITE,则可以使用PROMITE而不是回调
ctlLogin.login(ID,Password)
.then(LoginCallback)
.catch(console.log(err))
或者,如果希望LoginCallback函数超出函数范围(req、res、next),则需要通过创建回调函数在该函数中传递res,然后通过传递错误、结果和res或使用bind调用LoginCallback函数
function sendResponseToSever(res, err, myLoginResult){
if(err){
return res.send({
errors: err,
status: 500 // what ever status code you want to set
});
}
return res.json(results);
}
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password, sendResponseToSever.bind(null, res)
//using bind function
// OR
ctlLogin.login(ID,Password, function(err, myLoginResult){
sendResponseToSever(err, myLoginResult, res);
// now sendResponseToSever is a generic function which you can call
// from any route
});
});
});
但若你们想避免地狱,最受欢迎的方式是使用承诺。
正如您所提到的,要避免嵌套,可以使用承诺来避免嵌套
请查看您是否想学习承诺我将在您的案例中使用的解决方案(如果我们跳过使用承诺和其他更难的东西)是将函数绑定到上下文。 在将对象方法用作回调时,它通常用于保留对象上下文,但也可用于创建参数少于原始参数的函数(有时称为currying) 在javascript中,您可以在任何函数上使用方法
bind
绑定上下文。在函数调用期间,第一个参数是this
的值,其他参数只是参数值
使用bind
重写代码:
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password, LoginCallback.bind(null, res));
});
function LoginCallback(res, err, myLoginResult)
{
res.json(myLoginResult);
}
```我将在您的案例中使用的解决方案(如果我们跳过使用承诺和其他更难的东西)是将函数绑定到上下文。 在将对象方法用作回调时,它通常用于保留对象上下文,但也可用于创建参数少于原始参数的函数(有时称为currying) 在javascript中,您可以在任何函数上使用方法
bind
绑定上下文。在函数调用期间,第一个参数是this
的值,其他参数只是参数值
使用bind
重写代码:
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password, LoginCallback.bind(null, res));
});
function LoginCallback(res, err, myLoginResult)
{
res.json(myLoginResult);
}
```使用承诺,只需很少的重构,就可以轻松地将其重构为更具可读性的代码:
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password)
.then((result) => {
// handle success
})
.catch((err) => {
// handle failure
})
});
function Login(ID, password) {
return new Promise(resolve, reject) {
// run your query using a library that supports promises
.then((result) => resolve(result))
.catch((err) => {
//handle your error
reject(err)
})
}
}
使用承诺,只需很少的重构,就可以轻松地将其重构为更具可读性的代码:
router.get('/login', function(req,res,next) {
// send call to login function.
var ID= req.query.ID;
var Password = req.query.Password
ctlLogin.login(ID,Password)
.then((result) => {
// handle success
})
.catch((err) => {
// handle failure
})
});
function Login(ID, password) {
return new Promise(resolve, reject) {
// run your query using a library that supports promises
.then((result) => resolve(result))
.catch((err) => {
//handle your error
reject(err)
})
}
}
“太糟糕了,我需要将回调函数发送到登录方法”这是为什么?我想是为了同步工作。我的意思是,为什么你认为回调是糟糕的设计?它们相当标准,但如果你想要一个替代方案,你可以返回一个承诺。回调在javascript中大量使用。我认为这是过度使用。但我接受它是在节点环境中编程的有效方式。代码更难阅读但是,“这已经够糟糕了,我需要将回调函数发送到login方法”这是为什么?我想是为了同步工作。我的意思是,为什么你认为回调是糟糕的设计?它们相当标准,但如果你想要一个替代方案,你可以返回一个承诺。回调在javascript中大量使用。我认为这是过度使用。但我接受它是在节点环境中编程的有效方式。代码更难阅读尽管如此。我试图避免这种嵌套形式的编码-因为它越来越深。我虽然我的版本是平等的,但我猜它不是…我试图避免这种嵌套形式的编码-因为它越来越深。我虽然我的版本是平等的,但我猜它不是…干净的方式做它!干净的方式做它!