2017-03-16 83 views
0

我有一个路径做了一些处理,它应该返回一个回调。 这里是代码:node.js回调设计 - 如何在回调中使用res

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温控功能不知道对象资源。 我知道我可以将它传递给登录模块,只是为了让它作为回调函数的参数传递给我,但它看起来像一个糟糕的设计,它足够糟糕,我需要将回调函数发送到登录方法。

有没有更好的方法来做到这一点,仍然有可读代码?

+0

*“这是不好的使用bind

您的代码重写足够我需要发送回调函数到登录方法“*为什么? – 4castle

+0

我想同步工作。 – Dani

+0

我的意思是,你为什么认为回调是坏设计?他们是相当标准的,但如果你想要一个替代品,你可以返回一个承诺。 – 4castle

回答

1

我认为最好的办法是使用这个代码片段:

ctlLogin.login(ID,Password, function(myLoginResult){ 

      res.json(myloginResult); 

    }); 

在这种情况下,你应该在你的登录功能是这样的:

login(ID, Password, callback){ 
     //your treatment here 
     callback(result) 


    } 
+0

我试图避免这种编码嵌套形式 - 随着它越来越深入。我虽然我的版本是平等的,但我想这不是... – Dani

1

您可以创建自己的中间件来处理您在不同功能上的登录。下面是一个简单的应用程序明确我为你创建:

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!') 
}) 

你可以看到,我插在布线后app.get('/login', login, func...功能。

现在,如果您使用这些url参数http://localhost:3000/login?ID=1&Password=password访问网页,您应该会看到成功消息。如果更改任何参数名称或值,则应返回成功:false。

你应该多看一些关于制作自己Express Custom Middleware

+0

非常有趣,感谢文章参考。 – Dani

1

您正在使用loginCallback出的功能(REQ,水库,旁边),从而REQ,水库范围和未来超出范围,他们无法访问。你可以访问这个喜欢

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功能询问服务承诺可以使用的承诺,而不是回调

ctlLogin.login(ID,Password) 
    .then(LoginCallback) 
    .catch(console.log(err)) 

,或者如果你想LoginCallback功能出的功能范围(REQ,水库,接下来),那么你需要通过创建一个回调函数来传递该函数中的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 
    });   
    }); 
}); 

但是如果你想避免回调地狱,最好的方法是使用promise。 正如你所提到的你想避免嵌套,你可以通过使用promise来避免它。

请参阅https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise如果你想了解的承诺

1

我会在你的情况下使用(如果我们跳过使用承诺等更强硬的东西),该解决方案结合上下文的功能。 大多数情况下,它用于保留使用对象方法作为回调的对象上下文,但它也可以用来创建一个函数,其参数比原来的要少(有时称为currying)。

在JavaScript中,您可以使用方法bind在任何函数上绑定上下文。第一个参数是函数调用期间的值this,其他参数值只是参数值。

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); 
} 

```

1

这可以很容易地改制为更readable使用代码的承诺很少重构:

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) 
     }) 
    } 
}