gpt4 book ai didi

javascript - 将回调转换为 Promise 时出现问题

转载 作者:行者123 更新时间:2023-12-03 00:36:49 25 4
gpt4 key购买 nike

我是一个试图理解node.js的初学者。我尝试将回调转换为 Passport 本地策略中的 promise ,在转换为 promise 后,当我尝试登录时出现错误,提示“用户未定义”。我确信我在转换回调函数时做了一些不正确的事情,请您看一下我的代码并解释我哪里做错了。

这是之前的回调

exports.newLocalStrategy= new localStrategy(
(username,password,done)=>{
User.find({username: username},(err, user)=>{
if (err) throw err;
if(user.length == 0){
console.log("Unknown User");
return done(null,false,{message: 'unknown User'});

}
comparePassword(password,user[0].password, (err,isMatch)=>{
if (err) throw err;
if (isMatch){

return done(null, user);
return res.send("Loggedin");

}else{
console.log('invalid password');
return done(null, false, {message:"Invalid password"});
}
})
});
});
const comparePassword = (candidatePassword, hash, callback)=>{
bcrypt.compare(candidatePassword, hash, (err, isMatch)=>{
if (err) return callback(err);
callback(null, isMatch);
});
}

以及我将其变为 promise 后的代码:

 exports.newLocalStrategy= new localStrategy(
(username,password,done)=>{
//promise
User.find({username: username})
.then(user =>{
if(user.length ==0){
return done(null, false,{message: 'unknown user'})
}
})
.catch(err => {return done(null,err)})
comparePassword(password,user[0].password)
.then(isMatch => {
if (isMatch) return (done,null);
})
.catch(err=>{return done(null,err)})
});
const comparePassword = (candidatePassword, hash, callback)=>{
return new Promise((resolve,reject)=>{
bcrypt.compare(candidatePassword, hash, (err, isMatch)=>{
if (err) return reject(err);
resolve(null, isMatch);
});
})
}

我在 comparePassword(password,user[0].password) 这一行收到错误

最佳答案

这里有两个主要问题。由于您似乎希望继续使 newLocalStrategy 接受 done 回调,因此我假设您不希望它返回 promise ,而只是使用 promise 内部。

exports.newLocalStrategy = new localStrategy(
(username, password, done) => {
User.find({
username: username
})
.then(user => {
if (user.length == 0) {
return done(null, false, { message: 'unknown user' })
}
})
.catch(err => {
return done(null, err)
})

// this is in the wrong scope, `user` is not defined here
comparePassword(password, user[0].password)
.then(isMatch => {
if (isMatch) return (done, null);
})
.catch(err => {
return done(null, err)
})
});

const comparePassword = (candidatePassword, hash, callback) => {
return new Promise((resolve, reject) => {
bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
if (err) return reject(err);
// resolve takes only one parameter
resolve(null, isMatch);
});
})
}

进行更正后,它应该如下所示:

exports.newLocalStrategy = new localStrategy((username, password, done) => {
User.find({ username }).then(users => {
if (users.length === 0) {
throw new Error('unknown user');
} else {
return Promise.all([users, comparePassword(password, users[0].password)]);
}
}).then(([users, isMatch]) => {
if (isMatch) done(null, users);
else throw new Error('invalid password');
}).catch(err => {
done(null, false, err)
});
});

const comparePassword = (candidatePassword, hash) => {
return new Promise((resolve, reject) => {
bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
if (err) reject(err);
else resolve(isMatch);
});
});
};

其中最令人困惑的部分可能是该行

return Promise.all([users, comparePassword(password, users[0].password)]);

这可以简化为

return comparePassword(password, users[0].password);

如果users不必传递给下一个.then(),因为它被传递给done()如果有匹配的话。 Promise.all()接受一组 Promise 并在调用下一个 .then() 回调之前解析它们。 users 不是一个 promise ,但它会隐式转换为 Promise.resolve() 。在内部,并与从 comparePassword() 解析的值一起传递。

为了将来引用,您可以使用 util.promisify() 定义 comparePassword() :

const comparePassword = require('util').promisify(bcrypt.compare);

关于javascript - 将回调转换为 Promise 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53624950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com