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 route
app.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 route
app.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中大量使用。我认为这是过度使用。但我接受它是在节点环境中编程的有效方式。代码更难阅读尽管如此。我试图避免这种嵌套形式的编码-因为它越来越深。我虽然我的版本是平等的,但我猜它不是…我试图避免这种嵌套形式的编码-因为它越来越深。我虽然我的版本是平等的,但我猜它不是…干净的方式做它!干净的方式做它!