使用promisy重构护照本地策略。 .catch()的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用promisy重构护照本地策略。 .catch()的问题相关的知识,希望对你有一定的参考价值。
在快递+护照+本地策略应用程序中,我使用bcrypt
来哈希密码,这是有效的:
var bcrypt = require('bcrypt-nodejs');
familySchema.pre('save', function(next) {
var family = this;
var SALT_FACTOR = 14;
if (!family.isModified('password')) return next();
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
if (err) return next(err);
bcrypt.hash(family.password, salt, null, function(err, hash) {
if (err) return next(err);
family.password = hash;
next();
});
});
});
然后我重构使用promisify
和async/await
:
const bcrypt = require('bcrypt-nodejs');
const util = require('util');
const bcryptGenSalt = util.promisify(bcrypt.genSalt);
const bcryptHash = util.promisify(bcrypt.hash);
familySchema.pre('save', async function(next) {
var family = this;
const SALT_FACTOR = 14;
if (!family.isModified('password')) return next();
const salt = await bcryptGenSalt(SALT_FACTOR).catch(next);
const hash = await bcryptHash(family.password, salt, null).catch(next);
family.password = hash;
next();
});
- 这种重构实际上是否正确?
- 如何仔细检查
bcryptGenSalt
或bcryptHash
中的错误是否被正确捕获?有没有办法以某种方式“迫使”bcryptGenSalt
投掷错误,进行测试? - 下一步,如何使用
.catch(next)
util函数删除两个wrapAsync
:
wrapAsync.js
:
module.exports = fn => (req, res, next) => fn(req, res, next).catch(next);
以下尝试不起作用,错误:family.isModified()
不是函数,(可能因为this
不再正确)。如何处理wrapAsync的参数,因为next
应该是第三个参数?
familySchema.pre(
'save',
wrapAsync(async function(req, res, next) {
var family = this;
const SALT_FACTOR = 14;
debugger;
if (!family.isModified('password')) return next();
const salt = await bcryptGenSalt(SALT_FACTOR);
const hash = await bcryptHash(family.password, salt, null);
family.password = hash;
next();
})
);
答案
重构是不正确的,因为在.catch
语句之后,函数的其余部分将继续运行。因此,如果例如bcryptGenSalt
抛出错误,则调用next
(因为.catch(next)
),但它也将继续下一行代码,直到函数结束(再次调用next
)。
通常,在async
函数中,您可以在可能引发错误的语句周围使用try/catch
:
familySchema.pre('save', async function(next) {
const SALT_FACTOR = 14;
if (!this.isModified('password')) return next();
try {
const salt = await bcryptGenSalt(SALT_FACTOR);
const hash = await bcryptHash(this.password, salt, null);
this.password = hash;
return next();
} catch(err) {
return next(err);
}
});
有没有办法以某种方式“迫使”
bcryptGenSalt
投掷错误,进行测试?
这取决于您使用哪些工具进行测试,但是像sinon
这样的软件包可以存根现有的函数,因此您可以控制地然后抛出错误,然后您可以测试它们。
以上是关于使用promisy重构护照本地策略。 .catch()的问题的主要内容,如果未能解决你的问题,请参考以下文章