[英]Passing parameters to predefined callbacks in Javascript/NodeJs
我正在尝试使用bcrypt
扩展NodeJs后端的简单登录方法。 我的问题是我现在需要通过哈希步骤传递user
变量。 我当前的方法看起来像这样-并且自然在onPasswordHashed
的范围内未定义user
:
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
,然后在onResultReceived
方法中将其设置为userObj = user
。 然后, 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
。
您可以使用可以直接访问父级作用域中的变量的内联匿名回调,也可以使用.bind()
将参数添加到回调中,或者在您的特定序列情况下,可以将user
对象保存到范围更大的变量中它可用于后续回调。 请参localUser
示例中的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()
函数如何工作的信息或指向doc的链接,则也可能存在一种将数据从一个步骤传递到下一步骤的方法。
假设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
对象添加到下一个回调参数中,如下所示:
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
if (error) {
...
} else {
if (user) {
// prepend user to the callback arguments for the next callback
bcrypt.compare(req.body.password, user.password, this.bind(this, user));
} else {
...
}
}
},
function onPasswordHashed(user, error, hash) {
// user is passed in here from previous callback
if (error) {
...
} else {
// use this.user that was set by a previous
// step in the process
bcrypt.compare(user, hash, this);
}
},
...
);
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.