Express 使用promisy重构passport本地策略。.catch()的问题
在express+passport+local strategy应用程序中,我使用Express 使用promisy重构passport本地策略。.catch()的问题,express,error-handling,promise,this,Express,Error Handling,Promise,This,在express+passport+local strategy应用程序中,我使用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.
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
中的错误是否被正确捕获?有没有一种方法可以“强制”bcryptGenSalt抛出一个错误来进行测试bcryptHash
- 下一步,如何使用
util函数删除这两个wrapAsync
:.catch(Next)
wrapAsync.js
:
module.exports = fn => (req, res, next) => fn(req, res, next).catch(next);
以下尝试无效,错误:family.isModified()
不是函数(可能是因为此
不再正确)。
以及如何处理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抛出一个错误来进行测试
这取决于您用于测试的工具,但也有类似的包可以存根现有函数,这样您就可以可控地产生然后抛出错误,然后进行测试。重构是不正确的,因为在
.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抛出一个错误来进行测试
这取决于您用于测试的工具,但也有类似的包可以存根现有函数,这样您就可以可控地产生然后抛出错误,然后进行测试。我刚刚意识到我使用的是
bcrypt nodejs
包,而不是官方的bcrypt
!和bcrypt支持承诺。根据bcrypt文档(),如果没有提供回调函数,bcrypt将自动输出一个承诺。因此我可以删除promisify
部分。我刚刚意识到我使用的是bcrypt nodejs
包,而不是官方的bcrypt
!和bcrypt支持承诺。根据bcrypt文档(),如果没有提供回调函数,bcrypt将自动输出一个承诺。因此我可以删除promisify
部分。“因为在.catch语句之后,函数的其余部分将继续运行”-->这是否意味着应该避免中描述的模式?简而言之,他们使用一个wrapAsync()函数来自动向异步函数调用添加一个.catch(next)。“因为在.catch语句之后,函数的其余部分将继续运行”-->这是否意味着应该避免中描述的模式?简而言之,它们使用wrapAsync()函数自动向异步函数调用添加.catch(next)。