我正在尝试使用bcrypt
扩展我的NodeJs后端的简单登录方法。我的问题是我现在需要通过散列步骤传递user
变量。我当前的方法看起来像这样 - user
范围内自然onPasswordHashed
未定义:
signin : function(req, res, next) {
step (
function findUser() {
User.findOne({ "email": req.body.email }, this);
},
function onResultReceived(error, user) {
if (error) {
...
} else {
if (user) {
bcrypt.compare(req.body.password, user.password, this);
} else {
...
}
}
},
function onPasswordHashed(error, hash) {
if (error) {
...
} else {
bcrypt.compare(user.password, hash, this); // user is undefined here
}
},
...
);
},
原则上我可以:(a)使用bcrypt
的同步调用。但是,在某些时候,我可能会遇到没有同步函数调用可用的相同问题。 (b)我可以先定义var userObj = null
,然后在userObj = user
方法中设置onResultReceived
。然后,userObj
应在所有范围内都可见。但这似乎不是最佳做法。或者是吗?
从目前为止阅读起来,使用bind()
似乎还有很长的路要走。我只是不知道如何将它应用到我的身上。例如:
bcrypt.compare(req.body.password, user.password, this.bind({user: user}));
不起作用。我不知道step
包可能会在这里引起任何问题。处理回调链非常方便。
根据我的发现和测试,我可以覆盖回调,例如:
bcrypt.compare(req.body.password, user.password, this(user));
但有了这个,我当然会遗漏有关error
和hash
的信息。
答案 0 :(得分:1)
您可以使用可以直接访问父作用域中的变量的内联匿名回调,您可以使用.bind()
向回调添加参数,或者在您的特定序列情况下,可以保存{{1}对象到更高范围的变量,因此它可用于后续回调。请参阅此示例中的user
变量:
localUser
仅供参考,如果您提供一些有关signin : function(req, res, next) {
var localUser;
step (
function findUser() {
User.findOne({ "email": req.body.email }, this);
},
function onResultReceived(error, user) {
// save user variable to higher scoped variable so
// subsequent callbacks can access it
localUser = user;
if (error) {
...
} else {
if (user) {
bcrypt.compare(req.body.password, user.password, this);
} else {
...
}
}
},
function onPasswordHashed(error, hash) {
if (error) {
...
} else {
// use localUser from higher scope here that was set by a previous
// step in the process
bcrypt.compare(localUser.password, hash, this);
}
},
...
);
},
功能如何工作的信息或链接,可能还有一种方法可以将数据从一个步骤传递到下一步。
假设step()
函数来自this module,您也可以这样做:
step()
传递给每个连续回调的signin : function(req, res, next) {
step (
function findUser() {
User.findOne({ "email": req.body.email }, this);
},
function onResultReceived(error, user) {
// save user on our stepper object so it can be accessed by later callbacks
this.user = user;
if (error) {
...
} else {
if (user) {
bcrypt.compare(req.body.password, user.password, this);
} else {
...
}
}
},
function onPasswordHashed(error, hash) {
if (error) {
...
} else {
// use this.user that was set by a previous
// step in the process
bcrypt.compare(this.user, hash, this);
}
},
...
);
},
值是一个常用的函数对象,您可以将自己的属性附加到该函数对象。虽然这种方式比以前的版本更清晰,但它实际上更危险,因为您添加到this
对象的属性可能与this
函数的内部实现中使用的内容冲突。第一个选项(父作用域中的对象)完全是私有的,不会发生这种冲突。
现在了解有关step()
如何工作的更多信息,您可以使用step()
将.bind()
对象添加到下一个回调参数中,如下所示:
user